【问题标题】:Why does windows GDI use RGBA format for `COLORREF` instead of BGRA?为什么 Windows GDI 使用 RGBA 格式的“COLORREF”而不是 BGRA?
【发布时间】:2015-06-17 05:43:44
【问题描述】:

MSDN states:

当指定明确的 RGB 颜色时,COLORREF 值具有 以下十六进制形式:

0x00bbggrr

低位字节包含一个 红色的相对强度值;第二个字节包含一个 绿色的价值;第三个字节包含一个蓝色值。这 高位字节必须为零。单个字节的最大值是 0xFF。

来自wingdi.h

#define RGB(r,g,b)          ((COLORREF)((BYTE)(r) | ((BYTE)(g) << 8) | ((BYTE)(b) << 16)))

#define GetRValue(rgb)      ((BYTE)  (rgb) )
#define GetGValue(rgb)      ((BYTE) ((rgb) >> 8))
#define GetBValue(rgb)      ((BYTE) ((rgb) >> 16))

由于 windows 是 little endian,COLORREF 是 RGBA 格式。这看起来很奇怪,因为 Windows 内部使用的颜色格式不是 BGR(A)?

RGBQUAD 结构定义为

typedef struct tagRGBQUAD {
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;

不同于COLORREF,BGRA。

由于 bitblt 函数需要一个 COLORREF 值数组,这意味着如果 Windows 使用 BGRA 作为其本机格式,则每次调用期间总会有额外的从 RGBA 到 BGRA 的转换。

我记错了,但我还在某处读到过,winapi 中使用的像素格式有一种奇怪的混合。

谁能解释一下?

【问题讨论】:

  • 你的说法不正确;宏清楚地以 0x00bbggrr 顺序组装 COLORREF。再看一遍,或者用它们写一些代码并观察结果。
  • Windows 对 BMP 文件使用 OS/2 格式,而 OS/2 格式在一些方面与 Windows 喜欢的格式不同。一个是您已经注意到的:R 和 B 颠倒了。另一个是 OS/2 位图是自下而上而不是自上而下。
  • @RaymondChen 没错!因此,在指定位图的高度时,我总是必须放一个-。那么有没有办法在不经过GDI中的RGB格式转换的情况下进行blit?
  • 您可以将DIB选择到DC中并直接从中进行blt。 GDI 将根据需要进行颜色翻转。
  • BGRA 结构实际上是指颜色格式是 ARGB,一个 DWORD 或 4 字节 int 从末尾读取。不是吗?我试图弄清楚如何在结构中存储颜色,如果我希望颜色格式(在 32 位或 4 字节级别)为 RGBA,那么我必须将结构中的数字存储为 ABGR(向后)。当读取 int 或整个颜色时,它会从结构的 THE END 开始读取。

标签: c++ c winapi rgb


【解决方案1】:

COLORREF 可以追溯到像素格式标准化程度较低的时候。许多图形适配器仍在使用调色板而不是完整的 24 位或 32 位颜色,因此即使您的适配器需要重新排序字节,您也不需要做很多。一些图形适配器甚至将图像存储在单独的颜色平面中,而不是多通道颜色的单个平面中。那时没有“正确”的答案。

RGBQUAD 来自 BMP 格式,正如 Raymond Chen 在 cmets 中提到的,来自 OS/2 位图格式。

【讨论】:

    猜你喜欢
    • 2023-02-16
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多