当前位置: 代码迷 >> 综合 >> Mat转HBITMAP CBitmap
  详细解决方案

Mat转HBITMAP CBitmap

热度:27   发布时间:2023-10-19 11:53:51.0

本转换代码从opencv源码 imshow中提取并改造而成 源码来自与opencv4库 与openCV3有些许不同这里给出内部用到的转换代码

,拿到HBITMAP句柄后 再使用 CBitmap m_bitmap; m_bitmap.Attach(hbmp);便可以转换为CBitmap对象

HBITMAP MattoHBMP(cv::Mat & Image)
{HBITMAP hbmp = NULL;SIZE size = { Image.cols ,Image.rows };const int channels = 3;int bpp = Image.channels() * 8;assert(Image.rows >= 0 && Image.cols >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));unsigned char buffer[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)];BITMAPINFO* bmi = (BITMAPINFO*)buffer;//搞不懂这里为什么反转与下面的flip不是重复了么FillBitmapInfo(bmi, size.cx, size.cy, channels * 8, 0);void* dst_ptr = 0;hbmp = CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, (void **)&dst_ptr/*&pBits*/, NULL, 0);if (Image.channels() == 1)SetBitmapBits(hbmp, (DWORD)Image.total(), Image.data);else{cv::Mat dst(size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx * channels + 3) & -4);//Image.copyTo(dst);convertToShow(Image, dst, false);CV_Assert(dst.data == (uchar*)dst_ptr);//cv::flip(dst, dst, 0);}return hbmp;
}

下面的FiilBitmapInfo为库中源码 无任何修改


void FillBitmapInfo(BITMAPINFO * bmi, int width, int height, int bpp, int origin)
{assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);memset(bmih, 0, sizeof(*bmih));bmih->biSize = sizeof(BITMAPINFOHEADER);bmih->biWidth = width;bmih->biHeight = origin ? abs(height) : -abs(height);bmih->biPlanes = 1;bmih->biBitCount = (unsigned short)bpp;bmih->biCompression = BI_RGB;if (bpp == 8){RGBQUAD* palette = bmi->bmiColors;int i;for (i = 0; i < 256; i++){palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;palette[i].rgbReserved = 0;}}
}

接下来还有转换代码 均摘抄自openCV420

inline void CLayerData::convertToShow(const cv::Mat &src, cv::Mat &dst, bool toRGB)
{const int src_depth = src.depth();CV_Assert(src_depth != CV_16F && src_depth != CV_32S);cv::Mat tmp;switch (src_depth){case CV_8U:tmp = src;break;case CV_8S:cv::convertScaleAbs(src, tmp, 1, 127);break;case CV_16S:cv::convertScaleAbs(src, tmp, 1 / 255., 127);break;case CV_16U:cv::convertScaleAbs(src, tmp, 1 / 255.);break;case CV_32F:case CV_64F: // assuming image has values in range [0, 1)src.convertTo(tmp, CV_8U, 255., 0.);break;}cv::cvtColor(tmp, dst, toRGB ? cv::COLOR_BGR2RGB : cv::COLOR_BGRA2BGR, dst.channels());
}