位图到垫子/2D 数组
BITMAP to mat/2d array
我的目标是有一个程序来截屏游戏,然后从代码中读取图片。
我是 WIN API + 从未使用过位图的新手,所以我很难过,我是一个彻头彻尾的菜鸟。
我必须截屏的代码是(在堆栈溢出上找到它(:
HDC hScreenDC = GetDC(NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int width = GetDeviceCaps(hScreenDC, HORZRES);
int height = GetDeviceCaps(hScreenDC, VERTRES);
// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
我的想法是将"hBitmap"转换为 mat/2d 数组。 我搜索了互联网并找到了下一个解决方案:
将图像加载到 HBITMAP 句柄中。
从 HBITMAP 获取位图对象。
创建一个 DWORD 数组以从位图加载 bmBits。
将 DWORD 数组保存到 RGB 结构矩阵中。
第 1 步已经做到了,我有 var"hBitmap"。
对于步骤 2,我添加了下一个代码:
//Get BITMAP object from HBITMAP
BITMAP bitmap;
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
在删除 DC 之前。
我不知道如何执行步骤3和4。 如果有人向我展示,我会很高兴,因为我没有设法找到有关该主题的任何简单指南。 如果有其他更好的解决方案,我也很乐意听到它们。
编辑:试图用"Barmak Shemirani"答案将其保存为 .ppm,但它只向我显示了 4 个大方块?
注意:I +=4,我知道它的 RGBA 而不是 RGB,但 A 总是 255 法典:
using namespace std;
int main()
{
cout << "Hello World!n";
HDC hScreenDC = GetDC(NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int width = GetDeviceCaps(hScreenDC, HORZRES);
int height = GetDeviceCaps(hScreenDC, VERTRES);
// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
WORD bpp = 32; //32-bit bitmap
cout << "width=" << width << endl;
cout << "height=" << height << endl;
DWORD size = ((width * bpp + 31) / 32) * 4 * height;
BITMAPINFOHEADER bi = { sizeof(bi) };
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = bpp;
unsigned char* bits = new unsigned char[size];
int result = GetDIBits(hScreenDC, hBitmap, 0, height, bits, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
ofstream img(".ppm");
img << "P3" << endl;
img << 1536 << " " << 864 << endl;
img << "255" << endl;
for (int i = 0; i <= 864; i++) {
for (int j = 0; j < 1536; j+=4) {
int r = bits[i];
int g = bits[i + 1];
int b = bits[i + 2];
img << r << " " << g << " " << b << endl;
}
}
cout << "finished" << endl;
delete[]bits;
// clean up
SelectObject(hMemoryDC, hOldBitmap);//now we can destroy hMemoryDC & hBitmap
DeleteObject(hBitmap);
DeleteDC(hMemoryDC);
ReleaseDC(0, hScreenDC);
}
GetObject(hBitmap...)
将仅填充DIB的bm.bmBits
成员。但是在这里我们没有DIB。请改用GetDIBits
。下面的示例读取 32 位位图的像素以bits
。
WORD bpp = 32; //32-bit bitmap
DWORD size = ((width * bpp + 31) / 32) * 4 * height;
BITMAPINFOHEADER bi = { sizeof(bi) };
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = bpp;
unsigned char* bits = new unsigned char[size];
int result = GetDIBits(hdc, hBitmap, 0, height, bits, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
...
delete[]bits;
除此之外,您的代码还需要ReleaseDC(0, hScreenDC)
进行清理,而不是DeleteDC(hScreenDC)
,因为 DC 是由GetDC
获取的。
//cleanup:
SelectObject(hMemoryDC, hOldBitmap);//now we can destroy hMemoryDC & hBitmap
DeleteObject(hBitmap);
DeleteDC(hMemoryDC);
ReleaseDC(0, hScreenDC);
以 ppm/非二进制为单位节省:
ofstream img("filename.ppm");
img << "P3n";
img << width << " " << height << "n";
img << "255n";
for(int y = height - 1; y >= 0; y--)
{
for(int x = 0; x < width; x ++)
{
int i = (y * width + x) * 4;
int r = bits[i + 2];
int g = bits[i + 1];
int b = bits[i + 0];
img << r << " " << g << " " << b << " ";
}
img << "n";
}
相关文章:
- 2D数组来自文本输入,中间有空格
- 如何使用用户输入在C++中正确填充2D数组
- 如何在C++中检查2D数组中负值的输入验证
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何在C++函数中声明静态 2D 数组?
- 我已经阅读了很多关于 2d 数组的信息,但我在作业中使用它时遇到了麻烦
- 使用矢量将文本文件中的输入存储到 2D 数组中
- 获取 2D 数组 c++ 中的所有数字对
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 如何在构造函数中使用初始值设定项设置具有相同值的 2d 数组?
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 如何创建一个所有行大小不同的 2D 数组,并且用户将指定每行将有多少个元素?
- 使用指针算法修改函数中的 2D 数组
- 在C++中初始化和打印 2D 数组
- 有没有办法使用输入的维度初始化 2d 数组中的所有项目而不循环C++?
- C++ 2D 数组写入多个位置
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 如何从initializer_list初始化 2D 数组
- 交换函数不是在 C++ 中交换 2D 数组的元素