c++ - 如何将 BITMAPV5HEADER 与 CreateDIBitmap 函数一起使用

标签 c++ winapi gdi

我正在尝试使用 BITMAPV5HEADER创建具有 alpha channel 的位图:

BITMAPV5HEADER bi;
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = width;
bi.bV5Height = -height;
bi.bV5Planes = 1;
bi.bV5BitCount = 32;
bi.bV5Compression = BI_RGB;
bi.bV5SizeImage = 0;
bi.bV5XPelsPerMeter = 0;
bi.bV5YPelsPerMeter = 0;
bi.bV5ClrUsed = 0;
bi.bV5ClrImportant = 0;
bi.bV5AlphaMask = 0x000000FF;
bi.bV5RedMask = 0x0000FF00;
bi.bV5GreenMask = 0x00FF0000;
bi.bV5BlueMask = 0xFF000000;
bi.bV5CSType = LCS_sRGB;
bi.bV5Endpoints = CIEXYZTRIPLE();
bi.bV5GammaRed = 0;
bi.bV5GammaGreen = 0;
bi.bV5GammaBlue = 0;
bi.bV5Intent = LCS_GM_IMAGES;
bi.bV5ProfileData = 0;
bi.bV5ProfileSize = 0;
bi.bV5Reserved = 0;

*hBmp = CreateDIBitmap(hdc, (BITMAPINFOHEADER *) &bi, CBM_INIT, data, (BITMAPINFO *)&bi, DIB_RGB_COLORS);

但我不确定类型转换是否正确。 CreateDIBitmap() documentation不清楚,因为在字段定义中它说:

In const BITMAPINFOHEADER *lpbmih,

在描述中:

lpbmih [in]
A pointer to a bitmap information header structure, BITMAPV5HEADER.

最佳答案

是的,类型转换没问题。

BITMAPV5HEADER文档状态:

The BITMAPV5HEADER structure is the bitmap information header file. It is an extended version of the BITMAPINFOHEADER structure.

BITMAPV5HEADER 的前 11 个字段与 BITMAPINFOHEADER 中的字段匹配。因此,您可以安全地将类型转换的 BITMAPV5HEADER* 指针传递给 lpbmih 参数,其中需要一个 BITMAPINFOHEADER* 指针。

另一方面,lpbmi 参数是另一回事。它需要一个 BITMAPINFO* 指针,但您却给它一个类型转换的 BITMAPV5HEADER* 指针。从技术上讲,BITMAPV5HEADER 不是 BITMAPINFO 的扩展,因此您应该传入一个单独的 BITMAPINFO 变量,而不是您的 BITMAPV5HEADER 变量。

但是,BITMAPINFOBITMAPINFOHEADER 开头,因此 BITMAPV5HEADER 的前 11 个字段将满足 BITMAPINFO::bmiHeader 字段。并且您将 header 的 biBitCount 字段设置为 32,将 biCompression 字段设置为 BI_RGB,因此没有使用颜色表,因此 CreateDIBitmap () 不会尝试访问 BITMAPINFO::bmiColors 字段并最终读取您的 BITMAPV5HEADER 的 alpha/gamma 字段作为 RGB 值。因此,在这个特定的配置中,将类型转换的 BITMAPV5HEADER* 指针传递给 lpbmi 参数,其中 BITMAPINFO* 指针也是“安全的” ".

关于c++ - 如何将 BITMAPV5HEADER 与 CreateDIBitmap 函数一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42957269/

相关文章:

c++ - StretchBlt() 不创建镜像

c++ - C++ 中的单例类

c++ - 与 Win32 连接混淆 - 为什么这段代码有效?

c++ - 实例化基类 - Win32 对话框类

windows - 使用 WinAPI 进行全屏管理

C# GDI 将椭圆从一个点移动到另一个点并返回

c++ - 多次 dc->DrawLine() 还是一次 blit 更便宜?

c++ - 如何调整处理器总线倍频器

c++ - Cmake add_compile_definitions 但对于所有目标

c++ - 如何获取有关 Webbrowser 控件实例或 IE Webbrowser 的滚动条的信息?