我有一个设备相关位图的HBITMAP
句柄,由以下代码生成:
// copy screen to bitmap
HDC hScreen = GetDC(NULL);//don't use hwnd, it doesn't work for non native windows
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
我想访问(只读)位图的位,读取一些值,执行一些计算,然后丢弃它。
根据this answer,我不应该使用GetDIBits()
或GetBitmapBits()
,因为它们复制数据,而应该用途:
BITMAP bitmap;
GetObject(hBitmap, sizeof(bitmap), (LPVOID)&bitmap);
但是根据GetObject
's documentation:
如果hgdiobj
是通过调用CreateDIBSection
创建的位图的句柄,并且指定的缓冲区足够大,则GetObject
函数返回DIBSECTION
结构。此外,DIBSECTION
中包含的BITMAP
结构的bmBits
成员将包含指向位图位值的指针。
如果hgdiobj
是通过任何其他方式创建的位图的句柄,则GetObject
仅返回位图的宽度、高度和颜色格式信息。您可以通过调用GetDIBits
或GetBitmapBits
函数来获取位图的位值。
这是指在评论上述答案:
根据此https://msdn.microsoft.com/en-us/library/dd144904(v=vs.85).aspx,如果位图不是由CreateDIBSection
创建的,则bitmap.bmBit
指针将为空。
那么,有没有办法访问位图的位(RGB值),而不复制它们呢?
如果有帮助的话,位图所依赖的设备总是屏幕,所以我猜它总是24位或32位位图。
在this article中,关于如何将HBITMAP
保存到文件中,有以下章节:
// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)
if (cClrBits < 24) pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << cClrBits));
// There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel
else pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
所以,我真的不明白这里发生了什么,哪个是对的?
1条答案
按热度按时间hc8w905p1#
我不应该用
GetDIBits()
...因为他们复制数据......
如果有帮助的话,位图所依赖的设备总是屏幕,所以我猜它总是24位或32位位图。
根据您使用的具体硬件,像素的存储方式可能会有所不同(可能是
Rr Gg Bb
在一台计算机上,Bb Gg Rr 00
在另一台计算机上,RG Br gb
在第三台计算机上)。为了确保您知道数据格式,应该使用
GetDIBits()
,因为该函数不仅复制数据,而且还将数据转换为"已知"格式,该格式不依赖于硬件。使用
GetPixel()
是否比复制它更有效?如果你只想检查几个像素(eidogg.你想知道其中10个像素的颜色),它应该更有效率。
如果你对所有20000像素感兴趣,
GetDIBits()
应该更有效。pbmi = (PBITMAPINFO)LocalAlloc ...
所以,我真的不明白这里发生了什么...
GetDIBits()
支持各种位图格式,例如:在"24位"的情况下,
BITMAPINFO
结构只由一个BITMAPINFOHEADER
结构组成,我自己在这种情况下经常这样写代码:在"256色"的情况下,
BITMAPINFO
结构由一个BITMAPINFOHEADER
结构和后面的256个"R,G,B"元组(颜色Map)组成-因此与"24位"的情况相比,该结构需要更多的内存。请注意,首先存储图像的最后一行,如果该行的长度不是4字节的倍数,则在每行的末尾有填充字节。