Рисующее приложение в версии .NET, страница 19

Для оценки размеров и координат углов изображений, (поверх них) нанесем полупрозрачную сетку координат с шагом в 25 пикселов. Прежде всего измените размер формы так, чтобы разместить трансформированные копии изображения. Для этого вставьте в конструктор формы такой код:

Size = new Size(780, 520);

При работе с изображениями будем пользоваться текущим прямоугольником. Первоначально он имеет размеры (cx, cy) и размещен в позиции, которая задана парой координат (dx, dy).

Rectangle r = new Rectangle (dx, dy, cx, cy);

Далее создадим уменьшенную вдвое версию прямоугольника и переместим ее вниз на высоту изображения.

r = new Rectangle (dx, cy+dy, cx/2, cy/2);

После этого будем сдвигать прямоугольник с помощью метода Offset, например:

r.Offset (new Point (cx/2, 0));   // Сдвиг вправо на половину размера исходного изображения

Все трансформации выполнены с помощью одного и того же приема — задания новых координат трех характерных точек прямоугольного изображения: (левого верхнего угла, правого верхнего угла и левого нижнего угла). Эти точки должны стать элементами массива типа Point[] (в строго указанном порядке). Далее, при вызове DrawImage, надо подать этот массив в качестве параметра. Зная эту премудрость, вы легко поймете логику следующего кода.

protected override void OnPaint (PaintEventArgs e)

{

Graphics g = e.Graphics;

int dx = 25, dy = 25,

w = bitmap.Size.Width,

h = bitmap.Size.Height;

float

fx = w * g.DpiX / bitmap.HorizontalResolution,

fy = h * g.DpiY / bitmap.VerticalResolution;

int cx = (int)fx,    // Actual Size

cy = (int)fy;

Text = "width = " + w.ToString() + ", height = " + h.ToString() +

";    cx = " + cx.ToString() +  ", cy = " + cy.ToString();

GraphicsPath path = new GraphicsPath();

path.AddEllipse (dx, dy, cx, cy);

PathGradientBrush brush = new PathGradientBrush (path);

brush.CenterPoint = new PointF (cx/4, cy/4);

brush.CenterColor = Color.FromArgb (10, 255, 255, 0);

brush.SurroundColors = new Color[]{Color.FromArgb(200, 255, 0, 0)};

g.FillEllipse (brush, dx, dy, cx, cy);

ColorMatrix colorMatrix = new ColorMatrix (new float[][]

{

new float[] {1, 0, 0, 0, 0},

new float[] {0, 1, 0, 0, 0},

new float[] {0, 0, 1, 0, 0},

new float[] {0, 0, 0, 0.7F, 0},

new float[] {0, 0, 0, 0, 1}

});

ImageAttributes attr = new ImageAttributes();

attr.SetColorMatrix (colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

Rectangle r = new Rectangle (dx, dy, cx, cy);

g.DrawImage (bitmap, r, 0, 0, w, h, GraphicsUnit.Pixel, attr);

r = new Rectangle (dx, cy+dy, cx/2, cy/2);     // Уменьшенная версия прямоугольника изображения

//====== Готовимся вращать изображение на 90 градусов против часовой стрелки

Point[] rot = {

new Point (r.Left, r.Top + r.Height), // Новое положение левого верхнего угла

new Point (r.Left, r.Top),                 // Новое положение правого верхнего угла

new Point (r.Left + r.Width, r.Top + r.Height) // Новое положение левого нижнего угла

};

g.DrawImage (bitmap, rot);     // Изображаем с учетом массива rot

//====== Готовимся выполнить скос

r.Offset(new Point(cx/2, 0));  // Сдвиг вправо

Point[] skew = {

new Point (r.Left, r.Top),    // Новое положение левого верхнего угла и т.д.

new Point (r.Right, r.Top),

new Point (r.Left + r.Width/3, r.Bottom)

};

g.DrawImage (bitmap, skew);

//====== Готовимся выполнить сдвиг и сжатие

r.Offset(new Point(cx/2 + cx/8, -cy/2)); // Сдвиг вправо и вверх

g.DrawImage (bitmap, r);

//====== Готовимся к созданию эффекта отражения в зеркале

r.Offset(0, cy/2); // Сдвиг вниз

Point[] refl = {

new Point (r.Left + r.Width/3, r.Bottom), // Здесь происходит переворот поверхности

new Point (r.Right + r.Width/3, r.Bottom),

new Point (r.Left, r.Top)

};

g.DrawImage (bitmap, refl);

DrawGrid(g);       // Сетку изобразим в отдельном методе

}

public void DrawGrid (Graphics g)

{

Color clr = Color.FromArgb (80, 255, 0, 0);

Pen pen = new Pen (clr, 1);

Brush br = new SolidBrush(clr);

for (int i = 0; i < Size.Width; i+=25)

{

if (i%100 == 0)

{

g.DrawString (i.ToString(),Font,br,i-10,5);

g.DrawLine(pen, i, 20, i, Size.Height);

}

else

g.DrawLine(pen, i, 0, i, Size.Height);

}

for (int i = 0; i < Size.Height; i+=25)

{

if (i%100 == 0)

{

g.DrawString (i.ToString(), Font, br, 2, i-5);

g.DrawLine(pen, 20, i, Size.Width, i);

}

else

g.DrawLine(pen, 0, i, Size.Width, i);

}

}