Практическое руководство. Создание градиента вдоль контура
Класс PathGradientBrush позволяет выбрать способ заполнения фигуры постепенно сменяющимися цветами. Например, можно указать один цвет для центра пути, а другой — для его границы. Можно также указать отдельные цвета для нескольких выбранных точек вдоль границы пути.
Примечание.
В GDI+ путь — это последовательность линий и кривых, поддерживаемых объектом GraphicsPath. Дополнительные сведения о путях GDI+ см. в разделах Графические пути в GDI+ и Конструирование и рисование путей.
Примеры, приведенные в этой статье — это методы, вызываемые из обработчика событий элемента управления Paint.
Чтобы заполнить эллипс путем-градиентом
В следующем примере мы заполним эллипс градиентной кистью пути. В качестве центрального цвета задан синий, а для цвета границ — аквамариновый. На рисунке ниже показан эллипс с заливкой.
По умолчанию кисть градиента пути не работает за пределами пути. Если вы используете кисть градиента пути для заполнения фигуры вне границы пути, область экрана за пределами пути заполнена не будет.
На следующем рисунке показано, что происходит при изменении вызова Graphics.FillEllipse в следующем коде на
e.Graphics.FillRectangle(pthGrBrush, 0, 10, 200, 40)
:public void FillEllipseWithPathGradient(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
' Create a path that consists of a single ellipse. Dim path As New GraphicsPath() path.AddEllipse(0, 0, 140, 70) ' Use the path to construct a brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255) ' Set the color along the entire boundary ' of the path to aqua. Dim colors As Color() = {Color.FromArgb(255, 0, 255, 255)} pthGrBrush.SurroundColors = colors e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70)
Предыдущий пример кода предназначен для работы с Windows Forms и требует PaintEventArgs, который является параметром PaintEventHandler.
Указание точек на границе
В следующем примере создается градиентная кисть пути, основанная на пути в форме звезды. Код задает свойство CenterColor, которое устанавливает красный цвет в центреоиде звезды. Затем код задает свойство SurroundColors, чтобы указать различные цвета (хранящиеся в массиве
colors
) в отдельных точках массиваpoints
. Последняя инструкция кода заполняет контур в форме звезды с помощью кисти градиента пути.public void ConstructBrushFromStarShapedPath(PaintEventArgs e) { // Put the points of a polygon in an array. Point[] points = { new Point(75, 0), new Point(100, 50), new Point(150, 50), new Point(112, 75), new Point(150, 150), new Point(75, 100), new Point(0, 150), new Point(37, 75), new Point(0, 50), new Point(50, 50)}; // Use the array of points to construct a path. GraphicsPath path = new GraphicsPath(); path.AddLines(points); // Use the path to construct a path gradient brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color at the center of the path to red. pthGrBrush.CenterColor = Color.FromArgb(255, 255, 0, 0); // Set the colors of the points in the array. Color[] colors = { Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0), Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0), Color.FromArgb(255, 0, 0, 255), Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 0, 255, 0)}; pthGrBrush.SurroundColors = colors; // Fill the path with the path gradient brush. e.Graphics.FillPath(pthGrBrush, path); }
' Put the points of a polygon in an array. Dim points As Point() = { _ New Point(75, 0), _ New Point(100, 50), _ New Point(150, 50), _ New Point(112, 75), _ New Point(150, 150), _ New Point(75, 100), _ New Point(0, 150), _ New Point(37, 75), _ New Point(0, 50), _ New Point(50, 50)} ' Use the array of points to construct a path. Dim path As New GraphicsPath() path.AddLines(points) ' Use the path to construct a path gradient brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the color at the center of the path to red. pthGrBrush.CenterColor = Color.FromArgb(255, 255, 0, 0) ' Set the colors of the points in the array. Dim colors As Color() = { _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 255, 255), _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 255, 255), _ Color.FromArgb(255, 0, 0, 0), _ Color.FromArgb(255, 0, 255, 0)} pthGrBrush.SurroundColors = colors ' Fill the path with the path gradient brush. e.Graphics.FillPath(pthGrBrush, path)
В следующем примере рисуется градиент пути без объекта GraphicsPath в коде. Рассматриваемый в примере конструктор PathGradientBrush получает массив точек, но не требует объекта GraphicsPath. Обратите внимание, что PathGradientBrush используется для заполнения прямоугольника, а не пути. Прямоугольник больше, чем используемый для определения кисти закрытый путь, поэтому некоторые прямоугольники не окрашиваются кистью. На следующем рисунке показаны прямоугольник (обозначен пунктиром) и часть прямоугольника, окрашенная кистью градиента пути:
public void DrawPathGradentWthoutGraphicsPath(PaintEventArgs e) { // Construct a path gradient brush based on an array of points. PointF[] ptsF = { new PointF(0, 0), new PointF(160, 0), new PointF(160, 200), new PointF(80, 150), new PointF(0, 200)}; PathGradientBrush pBrush = new PathGradientBrush(ptsF); // 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.FromArgb(255, 255, 0, 0), // (0, 0) red Color.FromArgb(255, 0, 255, 0), // (160, 0) green Color.FromArgb(255, 0, 255, 0), // (160, 200) green Color.FromArgb(255, 0, 0, 255), // (80, 150) blue Color.FromArgb(255, 255, 0, 0)}; // (0, 200) red pBrush.SurroundColors = colors; // Set the center color to white. pBrush.CenterColor = Color.White; // Use the path gradient brush to fill a rectangle. e.Graphics.FillRectangle(pBrush, new Rectangle(0, 0, 160, 200)); }
' Construct a path gradient brush based on an array of points. Dim ptsF As PointF() = { _ New PointF(0, 0), _ New PointF(160, 0), _ New PointF(160, 200), _ New PointF(80, 150), _ New PointF(0, 200)} Dim pBrush As New PathGradientBrush(ptsF) ' An array of five points was used to construct the path gradient ' brush. Set the color of each point in that array. 'Point (0, 0) is red 'Point (160, 0) is green 'Point (160, 200) is green 'Point (80, 150) is blue 'Point (0, 200) is red Dim colors As Color() = { _ Color.FromArgb(255, 255, 0, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 255, 0), _ Color.FromArgb(255, 0, 0, 255), _ Color.FromArgb(255, 255, 0, 0)} pBrush.SurroundColors = colors ' Set the center color to white. pBrush.CenterColor = Color.White ' Use the path gradient brush to fill a rectangle. e.Graphics.FillRectangle(pBrush, New Rectangle(0, 0, 160, 200))
Настройка градиента пути
Одним из способов настройки кисти градиента пути является установка его свойства FocusScales. Масштаб фокуса определяет внутренний путь, находящийся внутри основного пути. Цвет для центра отображается везде внутри данного внутреннего пути, а не только в центральной точке.
В следующем примере создается кисть градиента пути на основе пути в форме эллипса. Код задает цвет границы синим, цвет центра — аквамариновым, а затем использует кисть градиента пути для заполнения пути в форме эллипса.
Затем код задает масштаб фокуса кисти градиента пути. Для шкалы фокуса x задано значение 0,3, а для y — 0,8. Код вызывает метод TranslateTransform объекта Graphics, чтобы последующий вызов FillPath заполнял эллипс, находящийся справа от первого эллипса.
Чтобы понять как работает масштабирование фокуса, представьте себе небольшой эллипс, центр которого совпадает с центром основного эллипса. Малый (внутренний) эллипс масштабируется (примерно по центру) горизонтально на коэффициент 0,3 и вертикально на коэффициент 0,8 от размеров главного эллипса. При переходе от границы внешнего эллипса к границе внутреннего цвет постепенно меняется от синего до аквамаринового. При переходе от границы внутреннего эллипса к общему центру цвет остается аквамариновым.
На рисунке ниже показан результат выполнения кода. Эллипс слева окрашен аквамариновым цветом только в центральной точке. Эллипс справа окрашен аквамариновым везде внутри внутреннего пути.
public void CustomizePathGradientBrush(PaintEventArgs e)
{
// Create a path that consists of a single ellipse.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, 200, 100);
// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush = new PathGradientBrush(path);
// Set the color along the entire boundary to blue.
Color[] color = { Color.Blue };
pthGrBrush.SurroundColors = color;
// Set the center color to aqua.
pthGrBrush.CenterColor = Color.Aqua;
// Use the path gradient brush to fill the ellipse.
e.Graphics.FillPath(pthGrBrush, path);
// Set the focus scales for the path gradient brush.
pthGrBrush.FocusScales = new PointF(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.
e.Graphics.TranslateTransform(220.0f, 0.0f);
e.Graphics.FillPath(pthGrBrush, path);
}
' Create a path that consists of a single ellipse.
Dim path As New GraphicsPath()
path.AddEllipse(0, 0, 200, 100)
' Create a path gradient brush based on the elliptical path.
Dim pthGrBrush As New PathGradientBrush(path)
' Set the color along the entire boundary to blue.
' Changed variable name from color
Dim blueColor As Color() = {Color.Blue}
pthGrBrush.SurroundColors = blueColor
' Set the center color to aqua.
pthGrBrush.CenterColor = Color.Aqua
' Use the path gradient brush to fill the ellipse.
e.Graphics.FillPath(pthGrBrush, path)
' Set the focus scales for the path gradient brush.
pthGrBrush.FocusScales = New PointF(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.
e.Graphics.TranslateTransform(220.0F, 0.0F)
e.Graphics.FillPath(pthGrBrush, path)
Настройка с помощью интерполяции
Настроить кисть градиента пути также можно через указание массива цветов интерполяции и массива позиций интерполяции.
В следующем примере создается кисть градиента пути на основе пути в форме треугольника. Код задает свойство InterpolationColors кисти градиента пути, чтобы указать массив цветов интерполяции (темно-зеленый, аквамариновый, синий) и массив позиций интерполяции (0, 0,25, 1). При переходе от границы треугольника к центральной точке цвет постепенно переходит от темно-зеленого к аквамариновому, а затем от аквамаринового к синему. Изменение с темно-зеленого на аквамариновый происходит на расстоянии, составляющем 25 процентов расстояния от темно-зеленого до синего.
На следующем рисунке показан треугольник, заполненный пользовательской кистью градиента пути.
public void CustomizeWithInterpolation(PaintEventArgs e) { // Vertices of the outer triangle Point[] points = { new Point(100, 0), new Point(200, 200), new Point(0, 200)}; // No GraphicsPath object is created. The PathGradientBrush // object is constructed directly from the array of points. PathGradientBrush pthGrBrush = new PathGradientBrush(points); Color[] colors = { Color.FromArgb(255, 0, 128, 0), // dark green Color.FromArgb(255, 0, 255, 255), // aqua Color.FromArgb(255, 0, 0, 255)}; // blue float[] relativePositions = { 0f, // Dark green is at the boundary of the triangle. 0.4f, // Aqua is 40 percent of the way from the boundary // to the center point. 1.0f}; // Blue is at the center point. ColorBlend colorBlend = new ColorBlend(); colorBlend.Colors = colors; colorBlend.Positions = relativePositions; pthGrBrush.InterpolationColors = colorBlend; // 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. e.Graphics.FillRectangle(pthGrBrush, 0, 0, 200, 200); }
' Vertices of the outer triangle Dim points As Point() = { _ New Point(100, 0), _ New Point(200, 200), _ New Point(0, 200)} ' No GraphicsPath object is created. The PathGradientBrush ' object is constructed directly from the array of points. Dim pthGrBrush As New PathGradientBrush(points) ' Create an array of colors containing dark green, aqua, and blue. Dim colors As Color() = { _ Color.FromArgb(255, 0, 128, 0), _ Color.FromArgb(255, 0, 255, 255), _ Color.FromArgb(255, 0, 0, 255)} ' Dark green is at the boundary of the triangle. ' Aqua is 40 percent of the way from the boundary to the center point. ' Blue is at the center point. Dim relativePositions As Single() = { _ 0.0F, _ 0.4F, _ 1.0F} Dim colorBlend As New ColorBlend() colorBlend.Colors = colors colorBlend.Positions = relativePositions pthGrBrush.InterpolationColors = colorBlend ' 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. e.Graphics.FillRectangle(pthGrBrush, 0, 0, 200, 200)
Установка центральной точки
По умолчанию центральная точка кисти градиента пути находится в центроиде пути, используемом для создания кисти. Расположение центральной точки можно изменить, задав свойство CenterPoint класса PathGradientBrush.
В следующем примере создается кисть градиента пути на основе пути в форме эллипса. Центр эллипса находится в точке (70, 35), но центральная точка кисти градиента пути находится в координатах (120, 40).
public void SetCenterPoint(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the center point to a location that is not // the centroid of the path. pthGrBrush.CenterPoint = new PointF(120, 40); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
' Create a path that consists of a single ellipse. Dim path As New GraphicsPath() path.AddEllipse(0, 0, 140, 70) ' Use the path to construct a brush. Dim pthGrBrush As New PathGradientBrush(path) ' Set the center point to a location that is not ' the centroid of the path. pthGrBrush.CenterPoint = New PointF(120, 40) ' Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255) ' Set the color along the entire boundary ' of the path to aqua. Dim colors As Color() = {Color.FromArgb(255, 0, 255, 255)} pthGrBrush.SurroundColors = colors e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70)
На следующем рисунке показаны заполненный эллипс и центральная точка кисти градиента пути:
Центральную точку кисти градиента пути можно установить в координаты за пределами пути, используемого для создания кисти. В следующем примере выполняется замена вызова для задания свойства CenterPoint в предыдущем коде.
public void SetCenterPointOutsidePath(PaintEventArgs e) { // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, 0, 140, 70); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the center point to a location that is not // the centroid of the path. pthGrBrush.CenterPoint = new PointF(145, 35); // Set the color at the center of the path to blue. pthGrBrush.CenterColor = Color.FromArgb(255, 0, 0, 255); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { Color.FromArgb(255, 0, 255, 255) }; pthGrBrush.SurroundColors = colors; e.Graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); }
pthGrBrush.CenterPoint = New PointF(145, 35)
На следующем рисунке показан достигнутый этой заменой результат:
На предыдущем рисунке точки в крайнем правом углу эллипса не окрашены чистым синим цветом (хотя выглядят очень близко к нему). Цвета в градиенте расположены так, как если бы заливка достигла точки (145, 35), где цвет должен быть чисто синим (0, 0, 255). Но заливка никогда не достигает (145, 35), потому что градиентная кисть пути красит только внутри ее пути.
Компиляция кода
Приведенные выше примеры предназначены для использования с Windows Forms и требуются PaintEventArgs e
, что является параметром обработчика Paint событий.
См. также
.NET Desktop feedback