Leadtools Bitmap与OpenCV Mat互相转换的最优实现方法
LeadTools Bitmap与OpenCV Mat双向转换最优方案
最优方案为**直接操作像素内存块完成转换,全程无磁盘IO,性能最高,仅需匹配两者的像素格式、宽高、行步长参数即可,C++实现如下:
前置匹配规则
- 两者默认24位彩色均为BGR通道顺序,无需额外转通道交换
- 均支持行字节对齐(步长),仅需匹配位深即可,对齐规则不同时逐行拷贝避免数据错位
LeadTools Bitmap转OpenCV Mat
#include <opencv2/opencv.hpp> #include "ltwrappr.h" cv::Mat LeadBitmapToMat(L_BitmapBase& leadBitmap) { // 锁定LeadTools位图内存 leadBitmap.Access(); int width = leadBitmap.GetWidth(); int height = leadBitmap.GetHeight(); int bpp = leadBitmap.GetBitsPerPixel(); int leadStride = leadBitmap.GetBytesPerLine(); uchar* leadData = (uchar*)leadBitmap.GetDataPointer(); // 匹配OpenCV Mat类型 int cvType; if (bpp == 8) cvType = CV_8UC1; else if (bpp == 24) cvType = CV_8UC3; else if (bpp == 32) cvType = CV_8UC4; else { leadBitmap.Release(); CV_Error(cv::Error::StsBadArg, "Unsupported bit depth"); return cv::Mat(); } // 深拷贝创建Mat,内存生命周期完全独立 cv::Mat mat(cv::Size(width, height), cvType); int cvStride = mat.step; // 步长一致直接整块拷贝,否则逐行拷贝 if (leadStride == cvStride) { memcpy(mat.data, leadData, leadStride * height); } else { for (int y = 0; y < height; y++) { memcpy(mat.data + y * cvStride, leadData + y * leadStride, width * (bpp / 8)); } } // 解锁LeadTools内存 leadBitmap.Release(); return mat; }
OpenCV Mat转LeadTools Bitmap
bool MatToLeadBitmap(cv::Mat& mat, L_BitmapBase& outLeadBitmap) { if (mat.empty()) return false; // 匹配位深 int bpp; if (mat.type() == CV_8UC1) bpp = 8; else if (mat.type() == CV_8UC3) bpp = 24; else if (mat.type() == CV_8UC4) bpp = 32; else { return false; } // 初始化对应参数的LeadTools位图 outLeadBitmap.Free(); if (outLeadBitmap.Create(mat.cols, mat.rows, bpp) != SUCCESS) { return false; } // 锁定LeadTools内存写入数据 outLeadBitmap.Access(); uchar* leadData = (uchar*)outLeadBitmap.GetDataPointer(); int leadStride = outLeadBitmap.GetBytesPerLine(); int cvStride = mat.step; int bytesPerPixel = bpp / 8; if (leadStride == cvStride) { memcpy(leadData, mat.data, cvStride * mat.rows); } else { for (int y = 0; y < mat.rows; y++) { memcpy(leadData + y * leadStride, mat.data + y * cvStride, mat.cols * bytesPerPixel); } } outLeadBitmap.Release(); return true; }
注意事项
- 如果LeadTools位图使用RGB通道顺序,转换后需调用
cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR)完成通道交换 - 如需支持16位灰度、浮点格式,仅需修改位深与Mat类型映射即可
- 其他编程语言实现逻辑完全一致,调用对应语言的内存拷贝API即可,比如C#使用
Marshal.Copy完成托管与非托管内存的拷贝
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

