Поделиться через


Создание градиента пути

Класс PathGradientBrush позволяет настроить способ заполнения фигуры постепенно изменяющимися цветами. Объект PathGradientBrush имеет путь границы и центральную точку. Можно указать один цвет для центра и другого цвета границы. Можно также указать отдельные цвета для каждой из нескольких точек вдоль границы.

Заметка

В GDI+путь — это последовательность линий и кривых, поддерживаемых объектом GraphicsPath. Дополнительные сведения о путях GDI+ см. в разделе Путей и Построение и Рисование Путей.

 

В следующем примере эллипс заполняется градиентной кистью по траектории. Цвет центра имеет синий цвет, а цвет границы имеет значение aqua.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

На следующем рисунке показан закрашенный эллипс.

иллюстрация, показывающая эллипс с градиентной заливкой

По умолчанию кисть градиента пути не расширяется за пределами границы пути. Если вы используете кисть с градиентом по пути для заполнения фигуры, которая выходит за пределы пути, то область за пределами пути не будет заполнена. На следующем рисунке показано, что происходит, если изменить вызов Graphics::FillEllipse в предыдущем коде на graphics.FillRectangle(&pthGrBrush, 0, 10, 200, 40).

иллюстрация с горизонтальным срезом предыдущего эллипса

Указание точек на границе

В следующем примере создается градиентная кисть пути из звездообразного пути. Код вызывает метод PathGradientBrush::SetCenterColor, чтобы задать цвет в центроиде звезды красным. Затем код вызывает метод PathGradientBrush::SetSurroundColors, чтобы задать различные цвета (хранящиеся в массиве colors) в отдельных точках массива points. Последняя инструкция кода заполняет путь, сформированный звездочкой, с помощью кисти градиента пути.

// Put the points of a polygon in an array.
Point points[] = {Point(75, 0),    Point(100, 50), 
                  Point(150, 50),  Point(112, 75),
                  Point(150, 150), Point(75, 100), 
                  Point(0, 150),   Point(37, 75), 
                  Point(0, 50),    Point(50, 50)};

// Use the array of points to construct a path.
GraphicsPath path;
path.AddLines(points, 10);

// Use the path to construct a path gradient brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to red.
pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));

// Set the colors of the points in the array.
Color colors[] = {Color(255, 0, 0, 0),   Color(255, 0, 255, 0),
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255), 
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0), 
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255),
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0)};

int count = 10;
pthGrBrush.SetSurroundColors(colors, &count);

// Fill the path with the path gradient brush.
graphics.FillPath(&pthGrBrush, &path);

На следующем рисунке показана заполненная звезда.

иллюстрация, показывающая пятиконечную звезду, которая заполняется от красного в центре до различных цветов в каждой точке звезды

В следующем примере создается градиентная кисть вдоль пути на основе массива точек. Цвет назначается каждому из пяти точек в массиве. Если бы вы соединили пять точек прямыми линиями, вы получили бы пятиугольник. Цвет также назначается центру (центроиду) этого многоугольника— в этом примере центр (80, 75) имеет значение белый. Последняя инструкция кода в примере заполняет прямоугольник кистью градиента пути.

Цвет, используемый для заполнения прямоугольника, белый (80, 75) и изменяется постепенно по мере перехода от (80, 75) к точкам в массиве. Например, при переходе от (80, 75) до (0, 0), цвет постепенно изменяется от белого к красному, и при переходе от (80, 75) до (160, 0), цвет постепенно изменяется от белого до зеленого.

// Construct a path gradient brush based on an array of points.
PointF ptsF[] = {PointF(0.0f, 0.0f), 
                 PointF(160.0f, 0.0f), 
                 PointF(160.0f, 200.0f),
                 PointF(80.0f, 150.0f),
                 PointF(0.0f, 200.0f)};

PathGradientBrush pBrush(ptsF, 5);

// An array of five points was used to construct the path gradient
// brush. Set the color of each point in that array.
Color colors[] = {Color(255, 255, 0, 0),  // (0, 0) red
                  Color(255, 0, 255, 0),  // (160, 0) green
                  Color(255, 0, 255, 0),  // (160, 200) green
                  Color(255, 0, 0, 255),  // (80, 150) blue
                  Color(255, 255, 0, 0)}; // (0, 200) red

int count = 5;
pBrush.SetSurroundColors(colors, &count);

// Set the center color to white.
pBrush.SetCenterColor(Color(255, 255, 255, 255));

// Use the path gradient brush to fill a rectangle.
graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

Обратите внимание, что в предыдущем коде нет объекта GraphicsPath. Конкретный конструктор PathGradientBrush в примере получает указатель на массив точек, но не требует объекта GraphicsPath. Кроме того, обратите внимание, что градиентная кисть пути используется для заполнения прямоугольника, а не пути. Прямоугольник больше пути, используемого для определения кисти, поэтому часть прямоугольника не окрашена кистью. На следующем рисунке показан прямоугольник (пунктирная линия) и часть прямоугольника, окрашенная кистью градиента пути.

иллюстрация, показывающая прямоугольник, ограниченный пунктирной линией, частично окрашенный многоцветным градиентом

Настройка градиента пути

Одним из способов настройки градиентной кисти по пути является установка её масштабов фокуса. Масштабы фокуса указывают внутренний путь, лежащий внутри основного пути. Цвет центра отображается везде внутри этого внутреннего пути, а не только в центре. Чтобы задать масштабы фокуса кисти градиента пути, вызовите метод PathGradientBrush::SetFocusScales.

В следующем примере создается градиентная кисть для пути, основанная на эллиптическом пути. Код задает цвет границы синий, задает цвет центра в аквамариновый, а затем использует градиентную кисть для пути для заполнения эллиптической фигуры.

Далее код задает масштабы фокуса кисти градиента пути. Для шкалы фокуса x задано значение 0,3, а для шкалы фокуса y задано значение 0,8. Код вызывает метод Graphics::TranslateTransform объекта Graphics, чтобы последующий вызов Graphics::FillPath заполнил эллипс, который расположится справа от первого эллипса.

Чтобы увидеть эффект масштабирования фокуса, представьте себе небольшой эллипс, который разделяет свой центр с основным эллипсом. Малый (внутренний) эллипс является основным эллипсом, масштабированным относительно его центра: по горизонтали на коэффициент 0,3 и по вертикали на 0,8. При переходе от границы внешнего эллипса к границе внутреннего эллипса цвет изменяется постепенно от синего до аква. При переходе от границы внутреннего многоточия к общему центру цвет остается аква.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 200, 100);

// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetGammaCorrection(TRUE);

// Set the color along the entire boundary to blue.
Color color(Color(255, 0, 0, 255));
INT num = 1;
pthGrBrush.SetSurroundColors(&color, &num);

// Set the center color to aqua.
pthGrBrush.SetCenterColor(Color(255, 0, 255, 255));
 
// Use the path gradient brush to fill the ellipse. 
graphics.FillPath(&pthGrBrush, &path);

// Set the focus scales for the path gradient brush.
pthGrBrush.SetFocusScales(0.3f, 0.8f);

// Use the path gradient brush to fill the ellipse again.
// Show this filled ellipse to the right of the first filled ellipse.
graphics.TranslateTransform(220.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

На следующем рисунке показаны выходные данные предыдущего кода. Эллипс слева является аква только в центральной точке. Эллипс справа - бирюзовый везде внутри внутреннего контура.

иллюстрация, показывающая два эллипса, которые переходят от аквамаринового к синему: первый имеет очень мало аквамаринового; второй имеет гораздо больше

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

В следующем примере создается градиентная кисть для пути на основе треугольника. Код вызывает метод PathGradientBrush::SetInterpolationColors градиентной кисти пути, чтобы указать массив цветов интерполяции (темно-зеленый, аква, синий) и массив позиций интерполяции (0, 0,25, 1). При переходе от границы треугольника к центру цвет изменяется постепенно с темно-зеленого на аква, а затем от аква до синего. Изменение от темно-зеленого к аква происходит в 25 процентов расстояния от темно-зеленого до синего.

// Vertices of the triangle
Point points[] = {Point(100, 0), 
                  Point(200, 200), 
                  Point(0, 200)};

// No GraphicsPath object is created. The PathGradient
// brush is constructed directly from the array of points.
PathGradientBrush pthGrBrush(points, 3);

Color presetColors[] = {
   Color(255, 0, 128, 0),    // Dark green
   Color(255, 0, 255, 255),  // Aqua
   Color(255, 0, 0, 255)};   // Blue

REAL interpPositions[] = {
   0.0f,   // Dark green is at the boundary of the triangle.
   0.25f,  // Aqua is 25 percent of the way from the boundary
           // to the center point.
   1.0f};  // Blue is at the center point.
                  
pthGrBrush.SetInterpolationColors(presetColors, interpPositions, 3);

// Fill a rectangle that is larger than the triangle
// specified in the Point array. The portion of the
// rectangle outside the triangle will not be painted.
graphics.FillRectangle(&pthGrBrush, 0, 0, 200, 200);

На следующем рисунке показаны выходные данные предыдущего кода.

иллюстрация, показывающая треугольник, который оттеняется от синего в центре, к аквамариновому и зеленому на краях

Настройка центра точки

По умолчанию центральная точка градиентной кисти пути находится в центроиде пути, используемом для создания кисти. Расположение центра можно изменить, вызвав метод PathGradientBrush::SetCenterPoint класса PathGradientBrush.

В следующем примере создается градиентная кисть для контура на основе эллипса. Центр эллипса находится в точке (70, 35), но центральная точка кисти градиента пути расположена в точке (120, 40).

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the center point to a location that is not the centroid of the path.
pthGrBrush.SetCenterPoint(Point(120, 40));

// Set the color at the center point to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

На следующем рисунке показан заполненный эллипс и центральная точка градиентной кисти для пути.

иллюстрация, показывающая эллипс, который заполняется от синего до голубого из центра вблизи одного конца

Вы можете задать центральную точку градиентной кисти по пути в место за пределами пути, который использовался для создания кисти. В приведенном выше коде при замене вызова PathGradientBrush::SetCenterPoint на pthGrBrush.SetCenterPoint(Point(145, 35))вы получите следующий результат.

иллюстрация, показывающая многоточие, которое заполняется от красного до желтого с центра точки, которая находится за пределами края многоточия

На предыдущем рисунке точки в правом углу эллипса не являются чистыми синим (хотя они очень близки). Цвета в градиенте расположены так, что если бы заливка достигла точки (145, 35), цвет стал бы чисто синим (0, 0, 255). Но заливка никогда не достигает точки (145, 35), потому что градиентная кисть рисует только внутри своего контура.