根据我对此功能的使用经验,我对GetDiBits有一些疑问。 我错误地创建了一个比我需要的大两倍的位图:
let h3 = document.createElement('h3');
h3.id = array[i].name;
...
else {
h3 = document.getElementById(array[i].name);
... // modify the h3 created earlier
}
我没有注意到,因为代码的下一部分有效。 我BitBlt屏幕的一部分在这个位图的一半:
HBITMAP hBmpSection = CreateCompatibleBitmap(ScreenDC, 2 * radius, 2 * radius);
然后我得到了相应的数组:
bmpSmallInfo.bmiHeader.biHeight = (2*radius / 2);
bmpSmallInfo.bmiHeader.biWidth = (2*radius / 2);
BitBlt(hSectionDC, 0, 0, bmpSmallInfo.bmiHeader.biWidth, bmpSmallInfo.bmiHeader.biHeight, ScreenDC, 0, 0, SRCCOPY);
当我将所有这些数据发送到另一台计算机时,图像完全正确(没有黑色边缘,就像发送超大位图的情况一样)。这意味着GetDiBits忽略了位图的正确大小,并使用BITMAPINFOHEADER中提供的大小,而不会崩溃。 (我正在使用Win10。)
这是正常的吗?由于我不想通过网络发送不需要的字节,我不得不问:GetDiBits是否输出了一个正确尺寸大小的数组:(4 * radius ^ 2)* 3或者它是否接受结构中的值: radius ^ 2 * 3 -ignoring padding - ?
答案 0 :(得分:1)
基本上你有这样的代码:
hbitmap = CreateCompatibleBitmap(hdc, max_width, max_height);
oldbmp = (HBITMAP)SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, x, y, SRCCOPY);
SelectObject(memdc, oldbmp);
int size = width_in_bytes_with_padding * height;
allocate size count memory ...
BITMAPINFOHEADER bi = { 40, width, height, 1, 24, BI_RGB };
GetDIBits(...);
您似乎在问的问题:如果width/height
小于max_width/max_height
,可以吗?
答案是肯定的。 GetDIBits
期望dataBuffer3
足够大以接收size
个字节。 width/height
应小于或等于max_width/max_height
请注意,BitBlt
是此代码中最慢的函数,这是您需要优化的函数。 CreateCompatibleBitmap
需要几微秒,你不会通过创建更大的位图来节省太多。
答案 1 :(得分:1)
GetDIBits 是GDI标准的一个相当奇怪的功能。而不是只采用HDC
或HBITMAP
的通常模式,它需要两者,并且对HBITMAP
参数施加了额外的限制。 iirc当您要求GDI(可能)相对于颜色表转换位图时使用此模式 - 即在8位或更低的图像中,您应该在HPALETTE
中选择HDC
。
MSDN上的GetDIBits function页面非常清楚 - LPBITMAPINFO
参数是:
指向BITMAPINFO结构的指针,指定所需的格式 对于DIB数据。
后续注释澄清,如果lpvBits
为NULL,则可以使用GetDIBits通过将位图属性写入BITMAPINFO
结构来检索位图属性。
回答您的具体问题; GetDIBits
使用您在BITMAPINFOHEADER
中提供的维度和格式输出到dataBuffer,并将剪辑&如果DDB
具有不同的维度或像素格式,则根据需要进行转换。