在开发图形或绘画应用程序时,经常需要一种功能强大的颜色选择器,它能够提供比Windows原生颜色对话框更多的特性。虽然Windows的颜色对话框在某些情况下已经足够使用,但对于需要处理图形的特殊应用程序来说,可能需要一些额外的功能,比如支持不同的颜色模型、精确的颜色选择、图形选择器控制、颜色值的快速转换、离屏颜色选择、复制十六进制代码到剪贴板、重置为之前的颜色、添加到颜色表等。
在编写图形应用程序时,用户可能希望无论他们输入的颜色模型是什么,都能保留他的颜色和颜色主题。这意味着HSL颜色必须以与La*b*颜色相同的方式存储。因此,编写了一组颜色选择控件,并将它们组合成一个颜色选择对话框,灵感来源于Adobe的颜色选择器。由于Adobe似乎使用了基于光谱白点的另一种加权格式,所以无法复制LAB部分的确切值。
颜色选择器的核心是颜色空间,它是ColorSelectionModule的基础。XYZ或以前的CIEXYZ被用作内部格式,因为它具有浮点数强度,并且包含所有其他光谱。LAB是XYZ空间的加权派生,基本上是从RGB派生的,就像HSV和CMYK一样。每种颜色空间只能转换到链中的下一个。有关详细规范和官方转换算法,请访问EasyRGB.com。
ColorSelectionModule的主要目标是支持不同的颜色模型。因此,必须记住所有选择控件都必须支持通用接口。这是通过使用类ColorSelectionModule实现的。它是一个抽象类,每个从它继承的类都提供了以下属性:
ColorSelectionModule协调fader和plane的更新。例如,如果滚动fader,plane的图像必须改变,反之亦然。同样,如果更改选定的颜色,两者都必须改变。
如果编写光栅图形编辑器,肯定希望能够从文档中选择颜色。这可以通过一个工具实现,更自然地说,是一个委托,它在屏幕上的每次鼠标移动时被调用。能够从屏幕的任何区域选择颜色,一方面更灵活,因为可以从另一个应用程序中选择颜色,另一方面,可能会有更多的错误,因为可能会遇到文档中的网格线或其他窗口,例如。
以下是使用Win32 API从HDC复制颜色的基本代码:
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern int GetPixel(IntPtr hdc, int x, int y);
这段代码封装在ColorLabel控件中,它还管理十六进制代码绘制和之前颜色的比较。
最后,将不同的控件组合在一个表单上,可以直接在代码中使用。但是,还应该能够像使用基本的.NET/Windows颜色对话框一样使用它。因此,添加了一个名为ColorDialogEx的类,它继承自Component。如果从工具箱拖到应用程序的表单上,它会吸附到组件区域,并且可以通过Color属性从代码中访问,该属性获取或设置System.Drawing.Color。