You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:18:05