C++屏幕截图 - 如何读取位图?
C++ screen capture - how to read the bitmap?
我希望程序(用 c++ 编写(从屏幕上读取像素,但我得到的响应似乎很混乱,变量start指示鼠标的位置。正确的方法是什么? 我使用了工作正常的 GetPixel((,但我需要一个完整的位图来提高效率。这是代码:
#include <Windows.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
int nScreenWidth;
int nScreenHeight;
HBITMAP GetScreenBmp(HDC hdc) {
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);
return hBitmap;
}
int main() {
nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HBITMAP hBitmap;
int times = 0;
while (!GetAsyncKeyState(VK_SPACE) && times<1000)
{
times++;
POINT p;
GetCursorPos(&p);
HDC hdc = GetDC(0);
hBitmap = GetScreenBmp(hdc);
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
if(0 == GetDIBits(hdc, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS)) {
cout << "error" << endl;
}
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
MyBMInfo.bmiHeader.biCompression = BI_RGB;
if(0 == GetDIBits(hdc, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS)) {
cout << "error2" << endl;
}
//**HERE** - position is wrong?
int start = (p.y*nScreenWidth+p.x)*4;
for(int i = start; i < start + 4; i+=4)
{
cout << "R:" << (int)lpPixels[i+2] << " G:" << (int)lpPixels[i+1] << " B:" << (int)lpPixels[i] << endl;
}
ReleaseDC(NULL, hdc);
delete[] lpPixels;
Sleep(1000);
}
DeleteObject(hBitmap);
return 0;
}
您正在强制BI_RGB
压缩,您不妨设置前 6 个值并仅调用GetDIBits
一次。由于位图高度从下到上开始,因此您必须为BITMAPINFOHEADER
提供负高度,否则从下到上读取。
确保该过程是 DPI 感知的。最简单的方法(但不是首选方法(是调用SetProcessDPIAware()
。对于每个hBitmap
分配调用DeleteObject(hBitmap)
int main()
{
SetProcessDPIAware();
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
while(!GetAsyncKeyState(VK_SPACE))
{
HDC hdc = GetDC(0);
POINT p;
GetCursorPos(&p);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, width, height);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, 0, 0, SRCCOPY | CAPTUREBLT);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
//use GetPixel for testing
COLORREF c = GetPixel(hdc, p.x, p.y);
printf("%02X%02X%02Xn", GetRValue(c), GetGValue(c), GetBValue(c));
BITMAPINFO bi = { 0 };
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = -height;
bi.bmiHeader.biBitCount = 32; //32-bit bitmap
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biCompression = BI_RGB;
//allocate 4 bytes per pixel for 32-bit
BYTE* lpPixels = new BYTE[height * width * 4];
if(0 != GetDIBits(hdc, hbitmap, 0, height, lpPixels,
&bi, DIB_RGB_COLORS))
{
int i = (p.y * width + p.x) * 4;
printf("%02X%02X%02Xnn",
lpPixels[i + 2], lpPixels[i + 1], lpPixels[i + 0]);
}
DeleteObject(hbitmap);
ReleaseDC(NULL, hdc);
delete[] lpPixels;
Sleep(1000);
}
return 0;
}
相关文章:
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何在快板的屏幕中显示子位图的绘制?
- CreateDIBSection为同一图像返回不一致的位图位值
- C++ 位图中的 ttc 字体
- 如何以滑动窗口方式从 std::bitset 读取位并将它们转换为 int?
- 使用 GDI+ 旋转位图,然后转换为 HDC
- 难以从 CImageList 设置菜单项位图
- C++屏幕截图 - 如何读取位图?
- 从位图图像文件读取像素数据值
- 正在从可执行资源中读取位图
- wx位图按钮读取类参数
- 从 C++ 中的位数组/位图中读取字段
- 读取位图图像时获取错误数据
- 我正在尝试读取位图文件
- 将字节数组从位图图像读取到坐标X和Y中
- 如何读取一个大的位图图像的大小
- FFMPEG -读取视频文件并转换为位图
- 无法使用c++读取位图文件的BITMAPFILEHEADER
- 如何从Windows剪贴板中读取位图
- 读取Linux inode位图