用三种颜色的渐变填充面板
Fill Panel with gradient in three colors
我正在做项目,我必须使用 C# 做一些颜色选择器。
所以我决定在 Win Forms 应用程序中将其作为具有此背景的面板。
背景应具有三种 rgb 颜色的渐变:红色 (0 - 255)、蓝色 (0 - 255) 和绿色 = 0。
但是我找不到任何关于我应该为此使用什么的信息。
我试着写了一些代码,这就是我所做的。
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
panel1.Paint += new PaintEventHandler(panel1_Paint);
panel1.Refresh();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Point startPoint = new Point(0, 0);
Point endPoint = new Point(150, 150);
LinearGradientBrush lgb =
new LinearGradientBrush(startPoint, endPoint, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 255, 255, 0));
Graphics g = e.Graphics;
g.FillRectangle(lgb, 0, 0, 150, 150);
// g.DrawLine(new Pen(Color.Yellow, 1.5f), startPoint, endPoint);
}
}
}
现在我有了这个渐变的面板
我应该用什么来获得第一张图片的渐变?
还有第二个问题:点击这个背景后像素颜色怎么办?
从鼠标点击事件参数e中,可以得到鼠标点击的精确坐标点:
Point clickPoint = e.GetPosition(backgroundControlWithImg);
然后使用类似以下内容获取该位置的图像颜色:
System.Drawing.Image image = backgroundControl.BackgroundImage;
Bitmap _bitmap = new Bitmap(image);
Color _color = bitmap.GetPixel(Point.x, Point.y);
类似的东西。您使用什么颜色选择器、WPF 或?
这是在 Paint
事件中使用多色 LinearGradientBrush
的示例:
LinearGradientBrush linearGradientBrush =
new LinearGradientBrush(panel4.ClientRectangle, Color.Red, Color.Yellow, 45);
ColorBlend cblend = new ColorBlend(3);
cblend.Colors = new Color[3] { Color.Red, Color.Yellow, Color.Green };
cblend.Positions = new float[3] { 0f, 0.5f, 1f };
linearGradientBrush.InterpolationColors = cblend;
e.Graphics.FillRectangle(linearGradientBrush, panel4.ClientRectangle);
您可以自由改变停止点的颜色数量、角度或分布。只需确保您始终拥有相同数量的颜色和停止点,并让它们从 0 开始到 1 结束。
构造函数中的颜色被忽略,顺便说一句..
要获得点击颜色,您可以对 MouseClick
:
进行编码
Color clickedColor = Color.Empty;
private void panel_MouseClick(object sender, MouseEventArgs e)
{
using (Bitmap bmp = new Bitmap( panel.ClientSize.Width, panel4.ClientSize.Height))
{
panel.DrawToBitmap(bmp,panel.ClientRectangle);
clickedColor = bmp.GetPixel(e.X, e.Y);
}
}
如果你想捕捉很多点击,最好将 Bitmap
保留在 class 级别变量中,而不是一直重新创建它。将它设置为面板的背景图像,如Kala 的回答假设也可能是一个不错的选择..
这应该回答了标题中的问题。但是,您的第一张图片没有显示三种颜色的渐变。它显示了具有四种颜色的二维渐变。对于这种更昂贵的着色方法,您应该将颜色放在 Bitmap
中并将其设置为 Panel
的 BackgroundImage
..
Update1 下面是一段创建二维渐变的代码:
Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
Bitmap bmp = new Bitmap(r.Width, r.Height);
float delta12R = 1f * (c2.R - c1.R) / r.Height;
float delta12G = 1f * (c2.G - c1.G) / r.Height;
float delta12B = 1f * (c2.B - c1.B) / r.Height;
float delta34R = 1f * (c4.R - c3.R) / r.Height;
float delta34G = 1f * (c4.G - c3.G) / r.Height;
float delta34B = 1f * (c4.B - c3.B) / r.Height;
using (Graphics G = Graphics.FromImage(bmp) )
for (int y = 0; y < r.Height; y++)
{
Color c12 = Color.FromArgb(255, c1.R + (int)(y * delta12R),
c1.G + (int)(y * delta12G), c1.B + (int)(y * delta12B));
Color c34 = Color.FromArgb(255, c3.R + (int)(y * delta34R),
c3.G + (int)(y * delta34G), c3.B + (int)(y * delta34B));
using ( LinearGradientBrush lgBrush = new LinearGradientBrush(
new Rectangle(0,y,r.Width,1), c12, c34, 0f) )
{ G.FillRectangle(lgBrush, 0, y, r.Width, 1); }
}
return bmp;
}
以下是使用方法:
public Form1()
{
InitializeComponent();
panel.BackgroundImage = Gradient2D(panel.ClientRectangle,
Color.Black, Color.FromArgb(255, 0, 255, 0), Color.Red, Color.Yellow);
}
这使用简单的 LinearGradientBrushes
,没有超出 Panel
高度的额外颜色列表。
请注意,Color.Green
是一种相当暗的色调,因此我使用 FromRgb
以获得更亮的绿色。如果您的 Panel
大于 256 像素,您可能希望通过填充更大的条纹来进行优化;如果它是垂直的,您可能需要更改循环以遍历 x 而不是 y..
结果如下:
要通过单击进行选择,您现在只需从 BackgroundImage
:
中读出颜色
private void panel_MouseClick(object sender, MouseEventArgs e)
{
clickedColor = ((Bitmap)panel.BackgroundImage).GetPixel(e.X, e.Y);
}
更新 2:
查看 this MSDN page 我们可以发现实际上有一个 built-in 工具可以创建 2D 渐变。
这是一个例子..:[=44=]
.. 和代码:
Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
List<Color> colors = new List<Color> { c1, c3, c4, c2 };
Bitmap bmp = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(bmp))
for (int y = 0; y < r.Height; y++)
{
using (PathGradientBrush pgb = new PathGradientBrush(getCorners(r).ToArray()))
{
pgb.CenterColor = medianColor(colors);
pgb.SurroundColors = colors.ToArray();
g.FillRectangle(pgb, 0, y, r.Width, 1);
}
}
return bmp;
}
这使用了两个简单的辅助函数。一个returns个矩形的角点:
public List<PointF> getCorners(RectangleF r)
{
return new List<PointF>() { r.Location, new PointF(r.Right, r.Top),
new PointF(r.Right, r.Bottom), new PointF(r.Left, r.Bottom)};
}
另一个根据 List<Color>
计算中值颜色。这用作 CenterColor
..:[=44=]
public static Color medianColor(List<Color> cols)
{
int c = cols.Count;
return Color.FromArgb(cols.Sum(x => x.A) / c, cols.Sum(x => x.R) / c,
cols.Sum(x => x.G) / c, cols.Sum(x => x.B) / c);
}
结果与使用 LinearGradientBrushes
条纹的结果几乎相同。它更简单,性能应该更好一些;这显然是我会推荐的..
注意颜色(或角)的顺序改变! SurroundColors
适用于矩形的对角..
注:
研究第一页可以发现,该画笔实际上有四种种不同的用途。
它们的不同之处在于设置方式(GraphicsPath
或 Point[]
)、要填充的颜色 collections(SurroundColors
或 InterpolationColors.Colors
)以及如何称呼它(用形状或路径)。而且结果也相差很大
另请注意,尽管提供了所有四种方式的代码,但仅显示了四种方式的 三种 种结果!..
我正在做项目,我必须使用 C# 做一些颜色选择器。
所以我决定在 Win Forms 应用程序中将其作为具有此背景的面板。
背景应具有三种 rgb 颜色的渐变:红色 (0 - 255)、蓝色 (0 - 255) 和绿色 = 0。
但是我找不到任何关于我应该为此使用什么的信息。
我试着写了一些代码,这就是我所做的。
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
panel1.Paint += new PaintEventHandler(panel1_Paint);
panel1.Refresh();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Point startPoint = new Point(0, 0);
Point endPoint = new Point(150, 150);
LinearGradientBrush lgb =
new LinearGradientBrush(startPoint, endPoint, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 255, 255, 0));
Graphics g = e.Graphics;
g.FillRectangle(lgb, 0, 0, 150, 150);
// g.DrawLine(new Pen(Color.Yellow, 1.5f), startPoint, endPoint);
}
}
}
现在我有了这个渐变的面板
我应该用什么来获得第一张图片的渐变?
还有第二个问题:点击这个背景后像素颜色怎么办?
从鼠标点击事件参数e中,可以得到鼠标点击的精确坐标点:
Point clickPoint = e.GetPosition(backgroundControlWithImg);
然后使用类似以下内容获取该位置的图像颜色:
System.Drawing.Image image = backgroundControl.BackgroundImage;
Bitmap _bitmap = new Bitmap(image);
Color _color = bitmap.GetPixel(Point.x, Point.y);
类似的东西。您使用什么颜色选择器、WPF 或?
这是在 Paint
事件中使用多色 LinearGradientBrush
的示例:
LinearGradientBrush linearGradientBrush =
new LinearGradientBrush(panel4.ClientRectangle, Color.Red, Color.Yellow, 45);
ColorBlend cblend = new ColorBlend(3);
cblend.Colors = new Color[3] { Color.Red, Color.Yellow, Color.Green };
cblend.Positions = new float[3] { 0f, 0.5f, 1f };
linearGradientBrush.InterpolationColors = cblend;
e.Graphics.FillRectangle(linearGradientBrush, panel4.ClientRectangle);
您可以自由改变停止点的颜色数量、角度或分布。只需确保您始终拥有相同数量的颜色和停止点,并让它们从 0 开始到 1 结束。
构造函数中的颜色被忽略,顺便说一句..
要获得点击颜色,您可以对 MouseClick
:
Color clickedColor = Color.Empty;
private void panel_MouseClick(object sender, MouseEventArgs e)
{
using (Bitmap bmp = new Bitmap( panel.ClientSize.Width, panel4.ClientSize.Height))
{
panel.DrawToBitmap(bmp,panel.ClientRectangle);
clickedColor = bmp.GetPixel(e.X, e.Y);
}
}
如果你想捕捉很多点击,最好将 Bitmap
保留在 class 级别变量中,而不是一直重新创建它。将它设置为面板的背景图像,如Kala 的回答假设也可能是一个不错的选择..
这应该回答了标题中的问题。但是,您的第一张图片没有显示三种颜色的渐变。它显示了具有四种颜色的二维渐变。对于这种更昂贵的着色方法,您应该将颜色放在 Bitmap
中并将其设置为 Panel
的 BackgroundImage
..
Update1 下面是一段创建二维渐变的代码:
Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
Bitmap bmp = new Bitmap(r.Width, r.Height);
float delta12R = 1f * (c2.R - c1.R) / r.Height;
float delta12G = 1f * (c2.G - c1.G) / r.Height;
float delta12B = 1f * (c2.B - c1.B) / r.Height;
float delta34R = 1f * (c4.R - c3.R) / r.Height;
float delta34G = 1f * (c4.G - c3.G) / r.Height;
float delta34B = 1f * (c4.B - c3.B) / r.Height;
using (Graphics G = Graphics.FromImage(bmp) )
for (int y = 0; y < r.Height; y++)
{
Color c12 = Color.FromArgb(255, c1.R + (int)(y * delta12R),
c1.G + (int)(y * delta12G), c1.B + (int)(y * delta12B));
Color c34 = Color.FromArgb(255, c3.R + (int)(y * delta34R),
c3.G + (int)(y * delta34G), c3.B + (int)(y * delta34B));
using ( LinearGradientBrush lgBrush = new LinearGradientBrush(
new Rectangle(0,y,r.Width,1), c12, c34, 0f) )
{ G.FillRectangle(lgBrush, 0, y, r.Width, 1); }
}
return bmp;
}
以下是使用方法:
public Form1()
{
InitializeComponent();
panel.BackgroundImage = Gradient2D(panel.ClientRectangle,
Color.Black, Color.FromArgb(255, 0, 255, 0), Color.Red, Color.Yellow);
}
这使用简单的 LinearGradientBrushes
,没有超出 Panel
高度的额外颜色列表。
请注意,Color.Green
是一种相当暗的色调,因此我使用 FromRgb
以获得更亮的绿色。如果您的 Panel
大于 256 像素,您可能希望通过填充更大的条纹来进行优化;如果它是垂直的,您可能需要更改循环以遍历 x 而不是 y..
结果如下:
要通过单击进行选择,您现在只需从 BackgroundImage
:
private void panel_MouseClick(object sender, MouseEventArgs e)
{
clickedColor = ((Bitmap)panel.BackgroundImage).GetPixel(e.X, e.Y);
}
更新 2:
查看 this MSDN page 我们可以发现实际上有一个 built-in 工具可以创建 2D 渐变。
这是一个例子..:[=44=]
.. 和代码:
Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
List<Color> colors = new List<Color> { c1, c3, c4, c2 };
Bitmap bmp = new Bitmap(r.Width, r.Height);
using (Graphics g = Graphics.FromImage(bmp))
for (int y = 0; y < r.Height; y++)
{
using (PathGradientBrush pgb = new PathGradientBrush(getCorners(r).ToArray()))
{
pgb.CenterColor = medianColor(colors);
pgb.SurroundColors = colors.ToArray();
g.FillRectangle(pgb, 0, y, r.Width, 1);
}
}
return bmp;
}
这使用了两个简单的辅助函数。一个returns个矩形的角点:
public List<PointF> getCorners(RectangleF r)
{
return new List<PointF>() { r.Location, new PointF(r.Right, r.Top),
new PointF(r.Right, r.Bottom), new PointF(r.Left, r.Bottom)};
}
另一个根据 List<Color>
计算中值颜色。这用作 CenterColor
..:[=44=]
public static Color medianColor(List<Color> cols)
{
int c = cols.Count;
return Color.FromArgb(cols.Sum(x => x.A) / c, cols.Sum(x => x.R) / c,
cols.Sum(x => x.G) / c, cols.Sum(x => x.B) / c);
}
结果与使用 LinearGradientBrushes
条纹的结果几乎相同。它更简单,性能应该更好一些;这显然是我会推荐的..
注意颜色(或角)的顺序改变! SurroundColors
适用于矩形的对角..
注:
研究第一页可以发现,该画笔实际上有四种种不同的用途。
它们的不同之处在于设置方式(GraphicsPath
或 Point[]
)、要填充的颜色 collections(SurroundColors
或 InterpolationColors.Colors
)以及如何称呼它(用形状或路径)。而且结果也相差很大
另请注意,尽管提供了所有四种方式的代码,但仅显示了四种方式的 三种 种结果!..