如果要将新版本的OpenCV的cv::Mat
显示到HWND上,之前都是说使用修改过的CvvImage
类进行显示,但是这个类有个缺点就是不能显示带有透明通道的cv::Mat,而目前好的方式是将cv::Mat
转换为MFC的CImage
类,不过之前别人写的都只是支持CV_8UC1
和CV_8UC3
的cv::Mat
对象,也不支持四通道的转换,我在本文中对这个功能进行了扩展,支持CV_8UC4
的cv::Mat
转换为CImage
类,这样就支持在HWND上显示透明的cv::Mat
图片了。
1 cv::Mat转换为CImage
下面就是我改写的代码,扩展了带有透明通道的cv::Mat
转换为CImage
bool RenderCvMatToHWnd::ConvertMat2CImage(const cv::Mat& src_img, CImage& dst_img)
{
if (src_img.empty())
{
return false;
}
int width = src_img.cols; //获取输入图像的宽度
int height = src_img.rows; //获取输入图像的高度
int channels = src_img.channels(); //获取输入图像的通道数
int type = src_img.type();
dst_img.Destroy();
switch (type)
{
case CV_8UC1:
{
dst_img.Create(width, -1 * height, 8 * channels);
unsigned char* dst_data = static_cast<unsigned char*>(dst_img.GetBits());
int step_size = dst_img.GetPitch(); //获取位图行与行之间相差的字节数
unsigned char* src_data = nullptr;
for (int i = 0; i < height; i++)
{
src_data = const_cast<unsigned char*>(src_img.ptr<unsigned char>(i)); //获取行指针
for (int j = 0; j < width; j++)
{
if (step_size > 0)
{
*(dst_data + step_size * i + j) = *src_data++;
} //像素的排列方式是自左上开始的
else
{
*(dst_data + step_size * i - j) = *src_data++;
}
}
}
break;
}
case CV_8UC3:
{
dst_img.Create(width, height, 8 * channels);
unsigned char* dst_data = static_cast<unsigned char*>(dst_img.GetBits());
int step_size = dst_img.GetPitch(); //获取位图行与行之间相差的字节数
unsigned char* src_data = nullptr;
for (int i = 0; i < height; i++)
{
src_data = const_cast<unsigned char*>(src_img.ptr<unsigned char>(i)); //获取行指针
for (int j = 0; j < width; j++)
{
for (int k = 0; k < 3; k++)
{
*(dst_data + step_size * i + j * 3 + k) = src_data[3 * j + k];
}
}
}
break;
}
case CV_8UC4:
{
dst_img.Create(width, height, 8 * channels);
unsigned char* dst_data = static_cast<unsigned char*>(dst_img.GetBits());
int step_size = dst_img.GetPitch(); //获取位图行与行之间相差的字节数
unsigned char* src_data = nullptr;
for (int i = 0; i < height; i++)
{
src_data = const_cast<unsigned char*>(src_img.ptr<unsigned char>(i)); //获取行指针
for (int j = 0; j < width; j++)
{
for (int k = 0; k < 4; k++)
{
*(dst_data + step_size * i + j * 4 + k) = src_data[4 * j + k];
}
}
}
break;
}
default:
break;
}
return true;
}
参考
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:OpenCV – cv::Mat转换为CImage,支持透明通道图片转换
原文链接:https://www.stubbornhuang.com/2816/
发布于:2023年09月25日 9:47:58
修改于:2023年09月25日 9:47:58
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
52