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

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

Такую кисть можно создать и управлять ею с помощью класса PathGradientBrush. Конструктор этого класса требует задать путь, вдоль которого заданы цвета, называемые SurroundColors. Проходя вдоль этого пути, алгоритм вычисляет градиент изменения цвета заливки с учетом цвета и положения одной особой точки, называемой центром. Градиентные кисти используются для закрашивания замкнутых фигур — стандартных графических примитивов или сложных областей, заданных пользователем. Итак, для работы с градиентной кистью нам надо:

¨  Создать объект класса GraphicsPath и задать путь в двухмерном пространстве (поверхности формы),

¨  Создать объект класса PathGradientBrush, задать его путь и свойства: CenterColor (тип Color), CenterPoint (тип PointF) и SurroundColors (тип Color[]).

¨  Выполнить это с помощью кода функции перерисовки.

Уберите строку кода, которая выводит изображение (мы добавим ее позже, но в ином варианте), и вставьте следующий код. Заметьте, что мы пользуемся факимческими размерами (cx, cy), а не размерами bitmap.

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);

Запустите и убедитесь, что эллипс закрашен градиентной кистью. Теперь наложим на этот эллипс наше изображение. При этом мы создадим матрицу, которая изменяет компонент alpha цвета всех точек растрового изображения, и оставляет неизменными другие компоненты. Вставьте код в конец метода OnPaint и запустите приложение.

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);

Вы должны увидеть результат наложения двух изображений. Он получен с помощью технологии blending, использующей матрицу (класс ColorMatrix) и класс ImageAttributes, позволяющий производить настройки процесса смешивания цветов, а также других способов цветовой коррекции (color-adjustment). Например, мы можем произвести: grayscale-adjustment, gamma-correction, подстройку цветовых порогов (color-threshold) и палитр (color-map tables). Кроме этого класс ImageAttributes позволяет управлять способами выравнивания текстур при наложении их на примитивы, перейти в цветовое пространство с другим базисом, а именно, CMYK (Cyan, Magenta, Yellow, Black). Методы класса дают возможность управлять интенсивностью отдельных компонентов цвета уже в этом пространстве,

Для оценки влияния alpha-канала измените значение третьего диагонального элемента матрицы. Для оценки влияния других элементов попробуйте изменить их, но предварительно пытайтесь предсказать результат качественно. Для этого придется применить аналитические вычисления.

Трасформация масштабов и формы изображения

Вы заметили в документации, что метод DrawImage имет 30 совмещенных версий. Некоторые его версии позволяют трансформировать изображение так, чтобы изменился его масштаб и координаты его углов. Для этого используется массив из трех точек. Сейчас мы покажем, как управлять координатами точек, чтобы добиться таких эффектов, как поворот, скос (skew), сжатие и сдвиг, создание эффекта отражения в зеркале (reflection). Результат, к которому мы стремимся показан на рисунке ниже.