| 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 | < Назад | Оглавление | Далее > |