Для оценки размеров и координат углов изображений, (поверх них) нанесем полупрозрачную сетку координат с шагом в 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);
}
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.