【发布时间】:2021-06-08 18:15:41
【问题描述】:
我需要在屏幕上找到一些图像。我决定做一个简单的比较循环。
我发现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 px,
MyBMInfo.bmiHeader.biSizeImage等于 4 096 000。是 rgba 还是什么? - 主要问题:虽然,没有错误,而且我在上一个问题中提到的值不为零,但是在代码底部的循环中,
lpPixels的所有值都是零,我没有得到任何输出。为什么?
【问题讨论】:
-
也许是个愚蠢的问题......但是你在哪里将屏幕的像素值复制到你的 hdc 中?
hdcSource(屏幕)和hdc(您的本地DC/位图)之间不应该有BitBlt或类似的吗? -
您正在从全新的位图中提取数据。尝试使用 BitBlt 将一些数据从
hdcSource复制到hdc。 -
和上面的cmets一样,不需要中间兼容位图。你可以使用
CreateDIBSection创建一个DIB并直接从屏幕blit到那个。 -
@AdrianMole @BenVoight 我试一试
BitBlt -
@BenVoigt 添加了
BitBlt(hdc, 0, 0, xw, yw, hdcSource, 0, 0, SRCCOPY);并且没有任何改变。xw和yw是窗口的宽度和高度。