适用于纯 Win32 的现代 Direct2D 颜色选择器





5.00/5 (14投票s)
C++,Direct2D,一个函数,你就能得到一个漂亮的颜色选择器
引言
很多时候,我需要一个选择器、一个漂亮的 HSL 滑块或一个 Alpha 通道。 这是一个用于你的代码的单文件库,它与 Direct2D 配合使用,并提供了一个用于选择颜色的现代界面。
Using the Code
你只需要调用一个函数
#include "colorpick.hpp"
COLORPICK p;
D2D1_COLOR_F c1 = {1.0f,0,0,1.0f}; // init with red
HRESULT hr = p.Show(0, c);
if (hr == S_OK) { ... } // Color is set
并且,可能传递一个包含更多选项的可选结构体
struct COLORPICKOPT
{
bool Alpha = 1;
int Mode = 1;
float rsl = 0.1f;
bool Dlg = 1;
bool LUpdate = 0;
bool AlsoUseSystem = 1;
bool UsePicker = 1;
float Resolution = 0.1f;
};
深入了解
RGB 和 HSL
让我们深入了解一下。 从 RGB
到 HSL
和反之的转换是通过 fromRGBtoHSL
和 fromHSLtoRGB
函数完成的 - 参见 更多。
绘图
所有绘制都由 ID2D1HwndRenderTarget
完成,它将在 WM_PAINT
上创建。 这将根据使用的模式
- 绘制 117 个带有预定义颜色的方块,用于 RGB 模式(取自 这里)。
- 在 HSL 模式下绘制一个色轮。 色轮逐像素逐行绘制。 每一行都有一个指定的
Hue
值,旋转时取最大值为 360,即整个圆圈。 这条线的半径是颜色的饱和度。Hue 滑块使用 360 值的停止Direct2D
线性画笔绘制。
色调条可以用线性画笔绘制
std::vector<D2D1_GRADIENT_STOP> gst(360);
for (int i = 0; i < 360; i++)
{
float hsl[3] = { 1,1,L };
hsl[0] = (360 - i) / 360.0f;
hsl[0] *= 6.0f;
float rgb[3] = {};
fromHSLtoRGB(hsl, rgb);
gst[i].position = i / 360.0f;
gst[i].color.r = rgb[0];
gst[i].color.g = rgb[1];
gst[i].color.b = rgb[2];
gst[i].color.a = 1.0f;
}
pGradientStops = 0;
lbr = 0;
p->CreateGradientStopCollection(
gst.data(),
360,
D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE_CLAMP,
&pGradientStops
);
p->CreateLinearGradientBrush(
D2D1::LinearGradientBrushProperties(
D2D1::Point2F(LRect.left, LRect.top),
D2D1::Point2F(LRect.right, LRect.bottom)),
pGradientStops,
&lbr);
这个线性渐变画笔现在可以用来绘制色调条。 其他条(S、L 或 R、G、B、Alpha)是纯色画笔。
键盘
WM_COMMAND
和 WM_KEYDOWN
用于处理 IDOK
/IDCANCEL
和 VK_RETURN
/VK_ESCAPE
以提交或取消颜色选择。
Inline Editing
点击 Alpha 值、R、G、B(在 RGB 模式下)或 H、S、L(在 HSL 模式下)值会显示一个内嵌编辑框(带有 ES_NUMBER
),允许你输入一个值(H 为 0-350,alpha 为 0-100,其他为 0-255)。 当编辑框处于活动状态时,VK_RETURN
/VK_ESCAPE
对编辑值起作用。
鼠标操作
点击
- RGB 值以选择点击的颜色
- 色轮以选择点击的颜色
- R、G、B 或 H、S、L 条以设置值
- Alpha、R、G、B 或 H、S、L 值以内嵌编辑值
拖动
- RGB 或 HSL 条以设置值
- 色轮以设置 HSL 值
滚轮操作
- 在条上旋转值
- 在 RGB/HSL 值上旋转值
系统对话框
对于那些习惯使用它的人来说,可以使用通用对话框选择器。 按下 "S
" 按钮将显示通用对话框并设置/获取所选值。
选择器
很多时候,你想选择你看到的颜色,但你不能命名它。 该控件包含一个选择器,你可以在其上点击,然后将其拖到屏幕上(颜色选择器之外),它会捕获其下的任何颜色。 它使用 SetCapture
API。
参数
- bool
Alpha
= 1; 默认情况下,颜色选择器也显示 alpha 控件。 如果你不想更改 Alpha,则传递 0。 返回的颜色将具有 1.0f 的 alpha。 - int
Mode
= 1; // 从 RGB 开始。 如果为 0,则从 HSL 开始。 - bool
Dlg
= 1; // 如果为 0,则它是一个窗口而不是一个对话框。 - bool
LUpdate
= 0; // 如果为 1,设置 L 时,色轮会更新(较慢) - bool
AlsoUseSystem
= 1; // 显示 "S" 按钮,允许使用系统通用控件 - bool
UsePicker
= 1; // 显示十字光标以启用选择器 - float
Resolution
= 0.1f; // 色轮的分辨率(较小的值 -> 较小的速度 -> 更好的视图)
项目
#include
colorpick.hpp 在你的应用程序中,你就准备好了。 github 存储库包含一个示例解决方案,你可以研究它。
历史
- 2020 年 6 月 2 日 - 第一个版本