美文网首页
OpenCV Mat和Bitmap转换

OpenCV Mat和Bitmap转换

作者: LiuJP | 来源:发表于2021-08-02 10:22 被阅读0次

官方文档 https://docs.opencv.org/java/3.0.0

Mat 保存了图像的一个多维矩阵;

Bitmap知识点

ANDROID_BITMAP_FORMAT_RGBA_8888

每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位

ANDROID_BITMAP_FORMAT_RGB_565

每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位

Bitmap.Config ARGB_4444:

每个像素占四位,即A=4,R=4,G=4,B=4,
那么一个像素点占4+4+4+4=16位(过时弃用)~~

Bitmap.Config ALPHA_8:

每个像素占四位,只有透明度,没有颜色。

对应CV中的关系
Bitmap.Config ALPHA_8 = 8UC1 = 8
8:8位
U:unsigned char
C:channel
1:数量
Bitmap.Config RGB_565 = 8UC2 = 16
Bitmap.Config RGB_8888 = 8UC4 = 16

mat2bitmap

void MatToBitmap(JNIEnv *env, Mat &mat, jobject &bitmap) {
    bool needPremultiplyAlpha = false;
    AndroidBitmapInfo info;
    void *pixels = 0;
    Mat &src = mat;
    try {
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(src.dims == 2 && info.height == (uint32_t) src.rows &&
                  info.width == (uint32_t) src.cols);
        CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
            printf("%s RGBA", __FUNCTION__);
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (src.type() == CV_8UC1) {
                cvtColor(src, tmp, COLOR_GRAY2RGBA);
            } else if (src.type() == CV_8UC3) {
                cvtColor(src, tmp, COLOR_RGB2RGBA);
            } else if (src.type() == CV_8UC4) {
                if (needPremultiplyAlpha)
                    cvtColor(src, tmp, COLOR_RGBA2mRGBA);
                else
                    src.copyTo(tmp);
            }
        } else {
            printf("%s BGR565", __FUNCTION__);
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            if (src.type() == CV_8UC1) {
                cvtColor(src, tmp, COLOR_GRAY2BGR565);
            } else if (src.type() == CV_8UC3) {
                cvtColor(src, tmp, COLOR_RGB2BGR565);
            } else if (src.type() == CV_8UC4) {
                cvtColor(src, tmp, COLOR_RGBA2BGR565);
            }
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);
        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
        return;
    }
}

bitmap2mat

void Detect::BitmapToMat(JNIEnv *env, jobject &bitmap, Mat &mat) {
    bool needUnPremultiplyAlpha = true;
    AndroidBitmapInfo info;
    void *pixels = nullptr;
    Mat &dst = mat;
    try {
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        dst.create(info.height, info.width, CV_8UC4);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (needUnPremultiplyAlpha)
                cvtColor(tmp, dst, COLOR_RGBA2BGR);
//                cvtColor(tmp, dst, COLOR_mRGBA2RGBA);
            else tmp.copyTo(dst);
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
//            cvtColor(tmp, dst, COLOR_BGR5652RGBA);
            cvtColor(tmp, dst, COLOR_RGBA2BGR);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);
        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        printf("%s %s \n", __FUNCTION__, e.err.c_str());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
        return;
    }
}

相关文章

网友评论

      本文标题:OpenCV Mat和Bitmap转换

      本文链接:https://www.haomeiwen.com/subject/eugsvltx.html