netlib.narod.ru | < Назад | Оглавление | Далее > |
Следующие четыре метода DrawImage указывают прямоугольник, в который нужно поместить изображение. Размеры прямоугольника даются в мировых координатах.
Методы DrawImage класса Graphics (выборочно)
void DrawImage(Image image, int x, int y, int cx, int cy) |
void DrawImage(Image image, float x, float y, float cx, float cy) |
void DrawImage(Image image, Rectangle rect) |
void DrawImage(Image image, RectangleF rectf) |
Эти методы подгоняют изображение под размеры прямоугольника, растягивая или сжимая его. Одно из распространенных применений данных методов — вывод изображения в пиксельном, а не метрическом размере. Если единицы измерения страницы — пикселы, просто вызовите:
grfx.DrawImage(image, x, y, image.Width, image.Height);
Приведенная ниже программа выводит изображение в пиксельном размере с выравниванием по центру клиентской области (или страницы принтера).
CenterPixelSizeImage.cs
//----------------------------------------------------- // CenterPixelSizeImage.cs (C) 2001 by Charles Petzold //----------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; class CenterPixelSizeImage: PrintableForm { Image image; public new static void Main() { Application.Run(new CenterPixelSizeImage()); } public CenterPixelSizeImage() { Text = "Center Pixel-Size Image"; image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg"); } protected override void DoPage(Graphics grfx, Color clr, int cx, int cy) { grfx.DrawImage(image, (cx - image.Width) / 2, (cy - image.Height) / 2, image.Width, image.Height); } }
Разрешение вашего монитора скорее всего превышает 72 dpi, и поэтому картинка будет иметь меньший размер, чем при выводе методом DrawImage.
Если вывести растровое изображение размером 220 × 240 пикселов с помощью этой версии DrawImage на принтер с разрешением 100 dpi, размер изображения составит примерно 2,2 × 2,4 дюйма. Если в методе DoPage сделать единицей измерения страницы пиксел, печатное изображение будет гораздо меньше — скорее всего вы столкнетесь с эффектом почтовой марки, распространенным в простых средах графического программирования.
Следующая программа загружает изображение и выводит его на всю клиентскую область (или печатную область страницы принтера).
ImageScaleToRectangle.cs
//------------------------------------------------------ // ImageScaleToRectangle.cs (C) 2001 by Charles Petzold //------------------------------------------------------ using System; using System.Drawing; using System.Windows.Forms; class ImageScaleToRectangle: PrintableForm { Image image; public new static void Main() { Application.Run(new ImageScaleToRectangle()); } public ImageScaleToRectangle() { Text = "Image Scale To Rectangle"; image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg"); } protected override void DoPage(Graphics grfx, Color clr, int cx, int cy) { grfx.DrawImage(image, 0, 0, cx, cy); } }
При значительном изменении ширины или высоты клиентской области изображение будет соответствующим образом искажаться.
Если вам нужно подогнать картинку под размер прямоугольника, такой эффект — явно не то, что требовалось. Вы, вероятно, хотите масштабировать изображение изотропно, т.е. одинаково в обоих направлениях. Вот программа, масштабирующая картинку более правильно.
ImageScaleIsotropic.cs
//---------------------------------------------------- // ImageScaleIsotropic.cs (C) 2001 by Charles Petzold //---------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; class ImageScaleIsotropic: PrintableForm { Image image; public new static void Main() { Application.Run(new ImageScaleIsotropic()); } public ImageScaleIsotropic() { Text = "Image Scale Isotropic"; image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg"); } protected override void DoPage(Graphics grfx, Color clr, int cx, int cy) { ScaleImageIsotropically(grfx, image, new Rectangle(0, 0, cx, cy)); } void ScaleImageIsotropically(Graphics grfx, Image image, Rectangle rect) { SizeF sizef = new SizeF(image.Width / image.HorizontalResolution, image.Height / image.VerticalResolution); float fScale = Math.Min(rect.Width / sizef.Width, rect.Height / sizef.Height); sizef.Width *= fScale; sizef.Height *= fScale; grfx.DrawImage(image, rect.X + (rect.Width - sizef.Width ) / 2, rect.Y + (rect.Height - sizef.Height) / 2, sizef.Width, sizef.Height); } }
Метод ScaleImageIsotropically работает практически всегда, кроме случаев, когда горизонтальное и вертикальное разрешения устройства различны (это встречается у некоторых принтеров) и когда параметр PageUnit имеет значение GraphicsUnit.Pixel (в принтерах по умолчанию используются другие единицы измерения).
Для начала метод ScaleImageIsotropically рассчитывает структуру SizeF, определяющую размер объекта Image в дюймах (если горизонтальное и вертикальное разрешения изображения одинаковы, данный этап не нужен). Затем вычисляется некоторый коэффициент, равный меньшему из двух значений: частному от деления высоты прямоугольника на высоту изображения и ширины прямоугольника на ширину изображения. Этот коэффициент fScale используется для изотропного масштабирования изображения в прямоугольнике. Затем метод определяет начало координат прямоугольника и передает полученную информацию методу DrawImage. Вот что получается:
Версии DrawImage, ориентированные на прямоугольник, могут не только масштабировать изображение, но и кое-что другое. Если указать отрицательную ширину, картинка будет повернута по вертикальной оси, и вы получите ее зеркальную копию. При отрицательной высоте метод поворачивает ее по горизонтальной оси и отображает вверх ногами. В любом случае верхний левый утол исходного, неперевернутого изображения позиционируется согласно координатам Point и PointF прямоугольника, указанными в DrawImage.
Следующая программа выводит четыре изображения, и некоторые из них имеют отрицательную ширину или высоту. Во всех четырех случаях второй и третий аргументы метода DrawImage указывают центр клиентской области.
ImageReflection.cs
//------------------------------------------------ // ImageReflection.cs (C) 2001 by Charles Petzold //------------------------------------------------ using System; using System.Drawing; using System.Windows.Forms; class ImageReflection: PrintableForm { Image image; public new static void Main() { Application.Run(new ImageReflection()); } public ImageReflection() { Text = "Image Reflection"; image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg"); } protected override void DoPage(Graphics grfx, Color clr, int cx, int cy) { int cxImage = image.Width; int cyImage = image.Height; grfx.DrawImage(image, cx / 2, cy / 2, cxImage, cyImage); grfx.DrawImage(image, cx / 2, cy / 2, -cxImage, cyImage); grfx.DrawImage(image, cx / 2, cy / 2, cxImage, -cyImage); grfx.DrawImage(image, cx / 2, cy / 2, -cxImage, -cyImage); } }
Вот эти четыре изображения.
Заметьте: при масштабировании программа использует пиксельный размер изображения.
netlib.narod.ru | < Назад | Оглавление | Далее > |