C++中如何调用实现Bitmap与Mat的互转
时间: 2025-06-22 14:43:11 浏览: 9
### C++ 中实现 Bitmap 与 Mat 的相互转换
#### 使用 OpenCV 进行图像操作时,经常需要在不同类型的图像表示之间进行转换。对于 C++ 编程而言,在 Windows 平台下通常会涉及到 `BITMAP` 结构体和 OpenCV 的核心类 `cv::Mat`。
#### 将 BITMAP 转换为 cv::Mat
为了完成从 `BITMAP` 到 `cv::Mat` 的转换,可以通过读取位图数据并将其填充到矩阵对象中来实现:
```cpp
#include <windows.h>
#include "opencv2/opencv.hpp"
// 假设 hBmp 是 HBITMAP 类型的句柄
HBITMAP hBmp;
BITMAP bitmap;
GetObject(hBmp, sizeof(BITMAP), &bitmap);
int width = bitmap.bmWidth;
int height = bitmap.bmHeight;
BYTE* bits = (BYTE*)bitmap.bmBits;
// 创建一个 Mat 对象用于存储 RGB 数据
cv::Mat img(height, width, CV_8UC3);
for(int y=0; y<height; ++y){
for(int x=0; x<width; ++x){
int idx = ((height-y-1)*width+x)*3;
img.at<cv::Vec3b>(y,x)[0] = bits[idx]; // B
img.at<cv::Vec3b>(y,x)[1] = bits[idx+1]; // G
img.at<cv::Vec3b>(y,x)[2] = bits[idx+2]; // R
}
}
```
此代码片段展示了如何遍历整个图片像素并将它们复制到新的 `cv::Mat` 实例里[^1]。
#### 将 cv::Mat 转换回 BITMAP
当需要把经过处理后的 `cv::Mat` 变成原始格式以便显示或其他用途时,则需执行相反的过程:
```cpp
// 获取 Mat 属性信息
int w = img.cols;
int h = img.rows;
int depth = img.depth();
int channels = img.channels();
// 准备创建 DIB 头部结构所需参数
BITMAPINFOHEADER bih;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = w;
bih.biHeight = -(LONG)h; // 正数代表自底向上扫描线顺序;负数则反之
bih.biPlanes = 1;
bih.biBitCount = static_cast<WORD>(depth * channels + 7)/8 * 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
// 计算每一行所需的字节数量(考虑对齐)
size_t row_stride = (((w * channels * depth / 8)+3)&~3);
// 分配内存空间给新构建出来的 BMP 文件的数据部分
std::vector<uint8_t> buffer(row_stride*h);
// 把 Mat 内容拷贝至缓冲区
uchar* pBuf = &buffer[0];
memcpy(pBuf,img.data,row_stride*h);
// 构造完整的 BITMAPINFO
BITMAPINFO bmi={bih};
// 创建兼容设备上下文(DC)
HDC hdc = GetDC(NULL);
HBITMAP hbmp = CreateDIBitmap(hdc,&bih,CBM_INIT,(void*)&img(0,0),(BITMAPINFO*)&bmi,DIB_RGB_COLORS);
DeleteDC(hdc);
```
这段程序说明了怎样依据已有的 `cv::Mat` 来生成相应的 `BITMAP` 形式的图形资源,并且能够正确设置其属性以适应不同的应用场景需求[^2]。
阅读全文
相关推荐















