栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Mat 与 Bitmap 互转 并操作像素

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Mat 与 Bitmap 互转 并操作像素

1. Android Bitmap 转 Mat
bool BitmapToMatrix(JNIEnv *env, jobject obj_bitmap, cv::Mat &matrix) {
    void *bitmapPixels;                                            // Save picture pixel data
    AndroidBitmapInfo bitmapInfo;                                   // Save picture parameters

    CV_Assert(AndroidBitmap_getInfo(env, obj_bitmap, &bitmapInfo) >=
              0);        // Get picture parameters
    CV_Assert(bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888
              || bitmapInfo.format ==
                 ANDROID_BITMAP_FORMAT_RGB_565);          // Only ARGB? 8888 and RGB? 565 are supported
    CV_Assert(AndroidBitmap_lockPixels(env, obj_bitmap, &bitmapPixels) >=
              0);  // Get picture pixels (lock memory block)
    CV_Assert(bitmapPixels);

    if (bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
        cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC4,
                    bitmapPixels);    // Establish temporary mat
        tmp.copyTo(
                matrix);                                                         // Copy to target matrix
    } else {
        cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC2, bitmapPixels);
        cv::cvtColor(tmp, matrix, cv::COLOR_BGR5652RGB);
    }

    //convert RGB to BGR
    cv::cvtColor(matrix, matrix, cv::COLOR_RGB2BGR);

    AndroidBitmap_unlockPixels(env, obj_bitmap);            // Unlock
    return true;
}
2. Mat 转 Bitmap 返回给 Java 层
jobject mat_to_bitmap(JNIEnv *env, Mat &src, bool needPremultiplyAlpha, jobject bitmap_config) {
    jclass java_bitmap_class = (jclass) env->FindClass("android/graphics/Bitmap");
    jmethodID mid = env->GetStaticMethodID(java_bitmap_class,
                                           "createBitmap",
                                           "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");

    jobject bitmap = env->CallStaticObjectMethod(java_bitmap_class,
                                                 mid, src.size().width, src.size().height,
                                                 bitmap_config);
    AndroidBitmapInfo info;
    void *pixels = 0;

    try {
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        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) {
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (src.type() == CV_8UC1) {
                cvtColor(src, tmp, CV_GRAY2RGBA);
            } else if (src.type() == CV_8UC3) {
                cvtColor(src, tmp, CV_RGB2RGBA);
            } else if (src.type() == CV_8UC4) {
                if (needPremultiplyAlpha) {
                    cvtColor(src, tmp, COLOR_RGBA2mRGBA);
                } else {
                    src.copyTo(tmp);
                }
            }
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            if (src.type() == CV_8UC1) {
                cvtColor(src, tmp, CV_GRAY2BGR565);
            } else if (src.type() == CV_8UC3) {
                cvtColor(src, tmp, CV_RGB2BGR565);
            } else if (src.type() == CV_8UC4) {
                cvtColor(src, tmp, CV_RGBA2BGR565);
            }
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return bitmap;
    } catch (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 bitmap;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
        return bitmap;
    }
}
3. Android Mat 操作像素 实现底片效果
extern "C"
JNIEXPORT jobject JNICALL
Java_com_cailei_opencvndk_MainActivity_filmEffect(JNIEnv *env, jobject thiz,
                                                  jobject origin_bitmap) {
    // 底片效果 利用 opencv 的 Mat
    AndroidBitmapInfo bitmapInfo;
    int ret = AndroidBitmap_getInfo(env, origin_bitmap, &bitmapInfo);
    if (ret != 0) {
        return NULL;
    }
    void *pixel;
    AndroidBitmap_lockPixels(env, origin_bitmap, &pixel);

    Mat src;
    BitmapToMatrix(env, origin_bitmap, src);


    // 区域截取
//    Mat srcROI = src(Rect(0, 0, bitmapInfo.width, bitmapInfo.height));

    int rows = src.rows;
    int cols = src.cols;

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            // 获取像素
            int b = src.at(i, j)[0];
            int g = src.at(i, j)[1];
            int r = src.at(i, j)[2];

            // 修改像素
            src.at(i, j)[0] = 255 - b;
            src.at(i, j)[1] = 255 - g;
            src.at(i, j)[2] = 255 - r;
        }
    }
    //get source bitmap's config
    jclass java_bitmap_class = (jclass) env->FindClass("android/graphics/Bitmap");
    jmethodID mid = env->GetMethodID(java_bitmap_class, "getConfig",
                                     "()Landroid/graphics/Bitmap$Config;");
    jobject bitmap_config = env->CallObjectMethod(origin_bitmap, mid);
    jobject _bitmap = mat_to_bitmap(env, src, false, bitmap_config);

    AndroidBitmap_unlockPixels(env, origin_bitmap);

    return _bitmap;

}

Mat 的初始化和我们平时写java代码的习惯不一样,它是先写height 再写 Width。这个位置一开始把我搞死了。我说为啥出不来效果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/943982.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号