【发布时间】:2015-06-17 05:43:44
【问题描述】:
当指定明确的 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 开始读取。