本轉換代碼從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());
}