如何在GDI+颜色中设置单独的颜色?

问题描述 投票:0回答:1

GDI+

Color
类具有返回特定颜色和 Alpha 通道值的函数
Get*
(如
GetR
GetRed
;其中两个用于同一件事!),同时缺少函数
Set
对于单独的频道。只有
SetValue
类型的函数可以一次性设置所有组件,这不太方便。

当然,我可以随时写

inline void SetAlpha(Color& color, BYTE alpha) {
    color.SetValue(Color::MakeARGB(alpha, color.GetR(), color.GetG(), color.GetB()));
}

对于其他

Color
组件也是如此,但是我是否缺少一些访问
Color
组件的直接方法?

如果不是,这样设计的原因可能是什么?这是一种兼容性还是性能的考虑?

c++ winapi gdi+ gdi
1个回答
0
投票

[A]我是否缺少一些访问颜色组件的直接方法?

不。各个颜色通道仅供读取访问。

如果不是,这样设计的原因可能是什么?这是一种兼容性还是性能的考虑?

可以肯定的是,这只能由

Color
类的作者来回答。因为我不是,所以我只能推测:

  • 兼容性可能是初始类设计从未收到更新的原因。在维持稳定 ABI 的约束下发展 C++ 类1 是非常具有挑战性的。
  • 性能考虑可能在设计中没有发挥作用。
  • 另一方面,
  • ARGB
    值的内存表示的布局兼容性是类建模的驱动因素。它唯一的数据成员 (
    Argb
    ) 是 
    DWORD
     的类型别名。没有任何虚函数,因此支持将保存 32bpp 像素数据的 
    DWORD*
     转换为 
    Color*
  • 考虑到将颜色数据存储为单个
  • DWORD
     值的设计使得无法提供用于写入访问的颜色通道访问器(
    BYTE& Color::GetAlpha()
     会因为与 
    bool& vector<bool>::operator[](size_type)
     相同的原因而被破坏)。
无论上述内容是否正确,

Color

都会按其方式发货。如果您需要设置单独的颜色通道,则需要自己实现此功能。您建议的实施是有效的,尽管我会选择不同的方法:

inline Color SetAlpha(Color src, BYTE alpha) { return Color(alpha, src.GetR(), src.GetG(), src.GetB()); }
这避免了引用,因此编译器不需要通过指针优化读写。 

Color

 对象的大小正好是 4 个字节,因此它可以方便地放入(子)寄存器中。作为奖励,它还支持链接,因此您可以编写以下代码:

auto const pink = Color().SetAlpha(255).SetRed(255).SetBlue(255);
通过整个 

Color

 类(隐式)
inline
-d(请参阅 
标头),编译器拥有评估其整套优化所需的一切。


1 GDI+ 是独一无二的。据我所知,它是唯一附带 C++ 接口的 API(位于扁平、C 风格 API 之上)。

© www.soinside.com 2019 - 2024. All rights reserved.