65.9K
CodeProject 正在变化。 阅读更多。
Home

创建颜色选择控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (8投票s)

2004年12月15日

5分钟阅读

viewsIcon

86148

downloadIcon

454

创建一个用户控件,用于从颜色映射中选择前景色和背景色。

Sample Image

引言

在做一个简单的图标编辑器时,我遇到了颜色选择的问题。当然,我可以使用颜色选择对话框,但因为它是一个对话框,所以用户无法直接使用。

看看常见的图形应用程序(例如,Paint Shop Pro),图像的编辑画布通常伴随着一个显示颜色映射的控件。然后,用户只需在控件上单击鼠标左键或右键,即可设置活动的前景色和背景色。

下面的代码演示了如何使用 .NET 框架的 alpha 混合功能轻松创建这样的控件。

创建控件

在实际创建控件之前,让我们先总结一下控件的功能:

  • 显示所有可用颜色的映射图
  • 通过在颜色映射图的任何位置单击鼠标左键来设置前景色属性
  • 通过在颜色映射图的任何位置单击鼠标右键来设置背景色属性

由于我们希望保持简单,该控件首先创建一个与控件画布大小相同的颜色映射位图。然后在 Paint 事件中,控件简单地将位图绘制到服务上。

由于画布大小和位图大小相同,画布的每个像素都对应于位图中的一个像素。选择颜色现在变成了一个查找单击坐标处的像素颜色(在 MouseUp 事件处理程序中完成)的问题。

颜色映射

最困难的部分是创建颜色映射位图,因为我们实际上是从三维空间映射到二维空间。呃……什么……你完全没听懂???

让我来解释一下。每种颜色都由三个值组成:红色 (R)、绿色 (G) 和蓝色 (B),也称为 RGB。对于 24 位颜色,每个值 R、G 或 B 的范围可以是 0..255(如果你还没弄明白,0..255 的范围恰好是 8 位,并且我们有 8 位的红色、8 位的绿色和 8 位的蓝色,总共就是 24 位颜色)。每种颜色都可以看作是具有轴:红色、绿色和蓝色三维空间中的一个坐标。所有颜色共同构成了 RGB 空间中大小为 255 的一个立方体。正是这个立方体,我们想要将其展平到一个二维画布上。

让我们快速计算一下:假设我们想显示所有颜色。使用 24 位,我们有 256*256*256 种颜色。现在如果你想在宽度为 256 像素的画布上显示这些颜色,那么长度将变为 256*256 = 65536 像素。我不了解你的显示器尺寸,但我认为公平地说,你的显示器无法支持 65536 像素的长度。此外,拉伸控件的宽度在这里也不起作用。所以显示所有颜色是不可能的。

所以问题归结为:如何显示颜色,使得用户可以选择所有类型的颜色,但不能选择所有颜色。

幸运的是,我们不必重新发明轮子。只需看看其他程序(例如,Paint Shop Pro),它们是如何解决这个问题的。基本上,它们会在黑白主背景上显示一组固定的六种基本颜色,这些颜色以重叠的圆圈显示,并且像光一样相互作用,也就是说,如果你混合红色和黄色,就会变成橙色。

创建六种基本颜色很简单。其中三种很容易找到:红色、绿色、蓝色(也称为三原色)。另外三种是混合色,可以通过两种三原色组合而成。

  • 红 + 绿 = 黄
  • 绿 + 蓝 = 青
  • 蓝 + 红 = 品红

以 RGB 值表示,三原色是:

  • 红 = (255, 0, 0)
  • 绿 = (0, 255, 0)
  • 蓝 = (0, 0, 255)

混合色是:

  • 黄 = (255, 255, 0)
  • 青 = (0, 255, 255)
  • 品红 = (255, 0, 255)

使用 LinearGradientBrush 可以创建黑白背景。下面是创建投影表面的代码示例。

lbrush = new LinearGradientBrush (ClientRectangle, 
         Color.FromArgb (255, 0, 0, 0), Color.FromArgb (255, 255, 255, 255), 0f);
g.FillRectangle (lbrush, ClientRectangle);

使用 PathGradientBrush 可以创建从基本颜色渐变为黑色的圆形。将 CenterColor 设置为基本颜色,将 SurroundColors 设置为黑色。

为了让圆形在黑白背景上像光一样作用,我们需要 alpha 通道。通过 alpha 通道,绘制到表面的颜色会与表面上现有的颜色混合。要启用 alpha 通道,请在绘制任何内容之前将 Graphics 实例 gCompositingMode 设置为 SourceOver

g.CompositingMode = CompositingMode.SourceOver;

另外,请确保绘制时指定的每种颜色都是带有 alpha 分量(也称为 ARGB 值)的 RGB 值。幸运的是,Color 类包含一个 static 方法 FromArgb。使用四个参数调用它,第一个参数是 alpha 值,其余参数是红色、绿色和蓝色值。下面是用代码示例绘制黄色圆。请注意指定的 alpha 值。

path = new GraphicsPath ();
path.StartFigure ();
path.AddEllipse (rect);
path.CloseFigure ();
pbrush = new PathGradientBrush (path);
pbrush.CenterColor = Color.FromArgb (255, 255, 0, 0);
pbrush.SurroundColors = new Color[] { Color.FromArgb (0, 0, 0, 0) };
g.FillEllipse (pbrush, rect);

上面的代码重复了六次,每次指定不同的基本颜色和不同的位置。

关注点

颜色映射控件可以方便快捷地选择颜色。但是,在映射图中找到相同的颜色两次是很困难的。为此,显示调色板的控件更合适。缺点是:由颜色网格绘制的调色板定义上可选择的颜色更少。

历史

  • 2004-12-15 - 初始发布。
  • 2004-12-29 - 更新 ForeColorBackColor 属性现在会触发相关的颜色更改事件。
© . All rights reserved.