GetDIBits returns 数组,所有值为 0
GetDIBits returns array with all values 0
我需要在屏幕上找到一些图像。我决定做一个简单的比较循环。
我发现 this answer 似乎很有帮助,并编写了下一个代码:
void Capt()
{
HDC hdcSource = GetDC(GetDesktopWindow()); // the source device context
HDC hdc = CreateCompatibleDC(hdcSource);
HBITMAP hSource = CreateCompatibleBitmap(hdcSource, xw, yw); // the bitmap selected into the device context
SelectObject(hdc, hSource);
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the BITMAPINFO structure from the bitmap
if (0 == GetDIBits(hdc, hSource, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
{
mb("error1");
IA(GetLastError());
}
// create the pixel buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
// We'll change the received BITMAPINFOHEADER to request the data in a
// 32 bit RGB format (and not upside-down) so that we can iterate over
// the pixels easily.
// requesting a 32 bit image means that no stride/padding will be necessary,
// although it always contains an (possibly unused) alpha channel
MyBMInfo.bmiHeader.biBitCount = 32;
MyBMInfo.bmiHeader.biCompression = BI_RGB; // no compression -> easier to use
// correct the bottom-up ordering of lines (abs is in cstdblib and stdlib.h)
MyBMInfo.bmiHeader.biHeight = abs(MyBMInfo.bmiHeader.biHeight);
// Call GetDIBits a second time, this time to (format and) store the actual
// bitmap data (the "pixels") in the buffer lpPixels
if (0 == GetDIBits(hdc, hSource, 0, MyBMInfo.bmiHeader.biHeight,
lpPixels, &MyBMInfo, DIB_RGB_COLORS))
{
mb("error2");
IA(GetLastError());
}
DeleteObject(hSource);
ReleaseDC(NULL, hdcSource);
for (int i = 0, j=0; i < MyBMInfo.bmiHeader.biSizeImage&&j<100; i++)
{
if (lpPixels[i] != 0)
{
char buf[1024] = {};
_itoa_s(lpPixels[i], buf, 10);
//output
}
}
}
两个问题:
- 我的屏幕分辨率是 1280x800=1 024 000 像素,
MyBMInfo.bmiHeader.biSizeImage
等于 4 096 000。是 rgba 还是什么?
- 主要问题:虽然没有错误,而且我在上一题中提到的值不为零,但是在代码底部的循环中,
lpPixels
的所有值都是零,我没有得到任何输出。为什么?
对于不带透明度的屏幕数据,只需将第四个字节(Alpha)设置为255,即不透明即可。
GetDIBits
得到的位图数据的颜色格式写在BGR(lpPixels
参数中)。如果我们想将数据赋值给使用RGB格式的字节数组,我们需要进行一些转换。
e.p.
for (size_t i = 0; i < myWidth * myHeight; i++)
{
size_t tempIndex = (i * 4);
// The colors are in BGR-format (windows format)
// Hence, the order is reversed
rgbPixels[tempIndex] = bgrPixels[tempIndex + 2]; // r
rgbPixels[tempIndex + 1] = bgrPixels[tempIndex + 1]; // g
rgbPixels[tempIndex + 2] = bgrPixels[tempIndex]; // b
rgbPixels[tempIndex + 3] = 255; // a (always 255)
}
已更新:
HDC hdc, hdcTemp;
RECT rect;
BYTE* bitPointer;
int x, y;
int red, green, blue, alpha;
hdc = GetDC(HWND_DESKTOP);
GetWindowRect(hWND_Desktop, &rect);
int MAX_WIDTH = rect.right;
int MAX_HEIGHT = rect.bottom;
hdcTemp = CreateCompatibleDC(hdc);
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = MAX_WIDTH;
bitmap.bmiHeader.biHeight = MAX_HEIGHT;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
SelectObject(hdcTemp, hBitmap2);
BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY);
for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4)
{
red = (int)bitPointer[i];
green = (int)bitPointer[i+1];
blue = (int)bitPointer[i+2];
alpha = (int)bitPointer[i+3];
}
我需要在屏幕上找到一些图像。我决定做一个简单的比较循环。
我发现 this answer 似乎很有帮助,并编写了下一个代码:
void Capt()
{
HDC hdcSource = GetDC(GetDesktopWindow()); // the source device context
HDC hdc = CreateCompatibleDC(hdcSource);
HBITMAP hSource = CreateCompatibleBitmap(hdcSource, xw, yw); // the bitmap selected into the device context
SelectObject(hdc, hSource);
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the BITMAPINFO structure from the bitmap
if (0 == GetDIBits(hdc, hSource, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
{
mb("error1");
IA(GetLastError());
}
// create the pixel buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
// We'll change the received BITMAPINFOHEADER to request the data in a
// 32 bit RGB format (and not upside-down) so that we can iterate over
// the pixels easily.
// requesting a 32 bit image means that no stride/padding will be necessary,
// although it always contains an (possibly unused) alpha channel
MyBMInfo.bmiHeader.biBitCount = 32;
MyBMInfo.bmiHeader.biCompression = BI_RGB; // no compression -> easier to use
// correct the bottom-up ordering of lines (abs is in cstdblib and stdlib.h)
MyBMInfo.bmiHeader.biHeight = abs(MyBMInfo.bmiHeader.biHeight);
// Call GetDIBits a second time, this time to (format and) store the actual
// bitmap data (the "pixels") in the buffer lpPixels
if (0 == GetDIBits(hdc, hSource, 0, MyBMInfo.bmiHeader.biHeight,
lpPixels, &MyBMInfo, DIB_RGB_COLORS))
{
mb("error2");
IA(GetLastError());
}
DeleteObject(hSource);
ReleaseDC(NULL, hdcSource);
for (int i = 0, j=0; i < MyBMInfo.bmiHeader.biSizeImage&&j<100; i++)
{
if (lpPixels[i] != 0)
{
char buf[1024] = {};
_itoa_s(lpPixels[i], buf, 10);
//output
}
}
}
两个问题:
- 我的屏幕分辨率是 1280x800=1 024 000 像素,
MyBMInfo.bmiHeader.biSizeImage
等于 4 096 000。是 rgba 还是什么? - 主要问题:虽然没有错误,而且我在上一题中提到的值不为零,但是在代码底部的循环中,
lpPixels
的所有值都是零,我没有得到任何输出。为什么?
对于不带透明度的屏幕数据,只需将第四个字节(Alpha)设置为255,即不透明即可。
GetDIBits
得到的位图数据的颜色格式写在BGR(lpPixels
参数中)。如果我们想将数据赋值给使用RGB格式的字节数组,我们需要进行一些转换。
e.p.
for (size_t i = 0; i < myWidth * myHeight; i++)
{
size_t tempIndex = (i * 4);
// The colors are in BGR-format (windows format)
// Hence, the order is reversed
rgbPixels[tempIndex] = bgrPixels[tempIndex + 2]; // r
rgbPixels[tempIndex + 1] = bgrPixels[tempIndex + 1]; // g
rgbPixels[tempIndex + 2] = bgrPixels[tempIndex]; // b
rgbPixels[tempIndex + 3] = 255; // a (always 255)
}
已更新:
HDC hdc, hdcTemp;
RECT rect;
BYTE* bitPointer;
int x, y;
int red, green, blue, alpha;
hdc = GetDC(HWND_DESKTOP);
GetWindowRect(hWND_Desktop, &rect);
int MAX_WIDTH = rect.right;
int MAX_HEIGHT = rect.bottom;
hdcTemp = CreateCompatibleDC(hdc);
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = MAX_WIDTH;
bitmap.bmiHeader.biHeight = MAX_HEIGHT;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
SelectObject(hdcTemp, hBitmap2);
BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY);
for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4)
{
red = (int)bitPointer[i];
green = (int)bitPointer[i+1];
blue = (int)bitPointer[i+2];
alpha = (int)bitPointer[i+3];
}