如何将屏幕图像放入内存缓冲区
How to get a screen image into a memory buffer?
我一直在寻找一种纯 WIN32 方法,将屏幕的图像数据放入缓冲区,以便稍后分析图像中的对象......可悲的是我没有找到。我现在对可以进行"屏幕打印"的库/类的建议持开放态度,但我仍然应该可以访问它的内存缓冲区。
任何帮助表示赞赏。
编辑:我忘了提到我将连续捕获屏幕,因此操作速度非常重要。也许有人知道一个好的图书馆?
// get screen DC and memory DC to copy to
HDC hScreenDC = GetDC(0);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
// create a DIB to hold the image
BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = GetDeviceCaps(hScreenDC, HORZRES);
bmi.bmiHeader.biHeight = -GetDeviceCaps(hScreenDC, VERTRES);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
LPVOID pBits;
HBITMAP hBitmap = CreateDIBSection(hMemoryDC, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);
// select new bitmap into memory DC
HGDIOBJ hOldBitmap = SelectObject(hMemoryDC, hBitmap);
// copy from the screen to memory
BitBlt(hMemoryDC, 0, 0, bmi.bmiHeader.biWidth, -bmi.bmiHeader.biHeight, hScreenDC, 0, 0, SRCCOPY);
// clean up
SelectObject(hMemoryDC, hOldBitmap);
DeleteDC(hMemoryDC);
ReleaseDC(0, hScreenDC);
// the image data is now in pBits in 32-bpp format
// free this when finished using DeleteObject(hBitmap);
有多种方法(您可以使用 DirectX),但可能最简单和最简单的是使用 GDI。
// GetDC(0) will return screen device context
HDC hScreenDC = GetDC(0);
// Create compatible device context which will store the copied image
HDC hMyDC= CreateCompatibleDC(hScreenDC );
// Get screen properties
int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int iBpi= GetDeviceCaps(hScreenDC ,BITSPIXEL);
// Fill BITMAPINFO struct
BITMAPINFO info;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = iScreenWidth;
info.bmiHeader.biHeight = iScreenHeight ;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = iBpi;
info.bmiHeader.biCompression = BI_RGB;
// Create bitmap, getting pointer to raw data (this is the important part)
void *data;
hBitmap = CreateDIBSection(hMyDC,&info,DIB_RGB_COLORS,(void**)&data,0,0);
// Select it into your DC
SelectObject(hMyDC,hBitmap);
// Copy image from screen
BitBlt(hMyDC, 0, 0, iScreenWidth, iScreenHeight, hScreenDC , 0, 0, SRCCOPY);
// Remember to eventually free resources, etc.
自从我这样做以来已经有一段时间了,所以我可能会忘记一些事情,但这就是它的要点。警告一句:这并不快;当屏幕移动很多时,捕获一帧可能需要 50 毫秒或更长时间。它基本上相当于按PrintScreen键。
相关文章:
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 如何从内存缓冲区加载张量流图
- 来自iostream或内存缓冲区的Apache Arrow表
- 如何正确复制内存缓冲区?
- 将不相邻的内存缓冲区视为连续缓冲区的数据结构
- 我可以在没有任何锁的情况下从不同的线程读取内存缓冲区吗?
- 设备驱动程序内存缓冲区处理器缓存问题
- C 接口到线性内存缓冲区
- 如何分配可执行的内存缓冲区
- 使用新的位置来创建静态常量指针,指向静态内存缓冲区
- 将内存缓冲区写入 std::stringstream
- 如何使用LEADTOOLS 19将图像效果应用于内存缓冲区中的JPEG
- CUDA sprintf 到全局/共享内存缓冲区
- 写入内存缓冲区时性能损失 (C++)
- 绘制和创建内存缓冲区 (Windows GDI)
- 如何将屏幕图像放入内存缓冲区
- std::从内存缓冲区复制到矢量
- 用c++获取内存缓冲区
- C -我如何gzip解压缩块文件到内存缓冲区
- 从内存缓冲区创建fstream对象