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

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (14投票s)

2020年6月2日

CPOL

3分钟阅读

viewsIcon

18773

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

让我们深入了解一下。 从 RGBHSL 和反之的转换是通过 fromRGBtoHSLfromHSLtoRGB 函数完成的 - 参见 更多

绘图

所有绘制都由 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_COMMANDWM_KEYDOWN 用于处理 IDOK/IDCANCELVK_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 日 - 第一个版本
© . All rights reserved.