我试图弄清楚如何从屏幕访问原始像素信息。到目前为止,我一直将屏幕捕获到 HBITMAP,填充 BITMAPINFO,然后创建此 BITMAPINFO 变量的指针以直接从内存读取。
我知道必须从文件中“删除”标头,因此我将指针直接前进到位图数据(将 sizeof(MyBMInfo2->bmiHeader) 添加到我的指针偏移量)。我还知道该位图是反转/自上而下的,第一个像素位于原始数据的末尾。我需要弄清楚如何从图像中给定的 X 和 Y 中提取 R G 和 B 字节,而这正是我无法做到的。
所以我问先生,一盏灯、一个片段或任何提示可以帮助我从 gdi32 重新创建 Bitmap.GetPixel(x,y) 的肮脏尝试(太慢了,我需要一个更好的)。
A snippet到目前为止我的源代码:
...
HDC hCaptureDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, nScreenWidth, nScreenHeight);
HGDIOBJ hOld = SelectObject(hCaptureDC, hBitmap);
BOOL bOK = BitBlt(hCaptureDC,0,0,nScreenWidth, nScreenHeight, hdc,0,0,SRCCOPY|CAPTUREBLT);
SelectObject(hCaptureDC, hOld); // always select the previously selected object once done
DeleteDC(hCaptureDC);
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the MyBMInfo structure from the bitmap
if(0 == GetDIBits(hdc, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS)) {
printf("error\n");
}
BITMAPINFO* MyBMInfo2 = &MyBMInfo;
BYTE* bitmapBits=(BYTE*)MyBMInfo2+sizeof(MyBMInfo2->bmiHeader);
//So... how do I acess X and Y RGB bytes now? xD
...
顺便说一下......还有其他更直接的方法可以在不引发内存保护错误的情况下执行此操作吗?或者...另一种更快的方式?
谢谢。
--Edit--
使用Barmak的代码我已经弄清楚如何根据当前光标位置访问X和Y rgb,下面是源代码:
#include <windows.h>
int main()
{
HWND hwnd = GetDesktopWindow();
RECT rc;
GetClientRect(hwnd, &rc);
int width = rc.right;
int height = rc.bottom;
if (width < 1 || height < 1)
{
OutputDebugStringA("error\n");
return 0;
}
HDC hdc = GetDC(hwnd);
HDC hCaptureDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, width, height);
HGDIOBJ hOld = SelectObject(hCaptureDC, hBitmap);
BitBlt(hCaptureDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY | CAPTUREBLT);
SelectObject(hCaptureDC, hOld);
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
BITMAPINFOHEADER bmpInfoHeader = { sizeof(BITMAPINFOHEADER) };
bmpInfoHeader.biWidth = width;
bmpInfoHeader.biHeight = height;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
DWORD size = ((width * bmpInfoHeader.biBitCount + 31) / 32) * 4 * height;
BYTE *bits = malloc(size);
if (GetDIBits(hdc, hBitmap, 0, height, bits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS))
{
OutputDebugStringA("success\n");
//you can use bits here
//access bits from upper-left to lower-right corner
POINT p;
GetCursorPos(&p);
int x = p.x;
int y = p.y;
int col = x;
int row = height - y - 1;
int index = (row * width + col) * 4;
BYTE b = bits[index + 0];
BYTE g = bits[index + 1];
BYTE r = bits[index + 2];
printf("r:%i g:%i b:%i \n",r,g,b);
}
else
{
OutputDebugStringA("error\n");
}
free(bits);
DeleteDC(hCaptureDC);
DeleteObject(hBitmap);
ReleaseDC(hwnd, hdc);
return 0;
}
非常感谢谢米拉尼先生。对于谁对我的答案投了反对票,请考虑撤回它? :)
和平。