700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android jni返回bitmap JNI 层 Bitmap 转 OpenCV Mat

android jni返回bitmap JNI 层 Bitmap 转 OpenCV Mat

时间:2023-12-24 01:16:32

相关推荐

android jni返回bitmap JNI 层 Bitmap 转 OpenCV Mat

JNI 层 Bitmap 转 OpenCV Mat

Java 提供的图片类型大多是 Bitmap 类型(ARGB_8888 或 RGB_565)

那么如果需要使用 OpenCV 进行处理,需要对 Bitmap 转 cv::Mat。

假设输入的图片为:jobject obj_bitmap

输出的图片为:jobject obj_bitmapOut

#include

#include

#include

#include

#define ASSERT(status, ret) if (!(status)) { return ret; }

#define ASSERT_FALSE(status) ASSERT(status, false)

bool BitmapToMatrix(JNIEnv * env, jobject obj_bitmap, cv::Mat & matrix) {

void * bitmapPixels; // 保存图片像素数据

AndroidBitmapInfo bitmapInfo; // 保存图片参数

ASSERT_FALSE( AndroidBitmap_getInfo(env, obj_bitmap, &bitmapInfo) >= 0); // 获取图片参数

ASSERT_FALSE( bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888

|| bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGB_565 ); // 只支持 ARGB_8888 和 RGB_565

ASSERT_FALSE( AndroidBitmap_lockPixels(env, obj_bitmap, &bitmapPixels) >= 0 ); // 获取图片像素(锁定内存块)

ASSERT_FALSE( bitmapPixels );

if (bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {

cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC4, bitmapPixels); // 建立临时 mat

tmp.copyTo(matrix); // 拷贝到目标 matrix

} else {

cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC2, bitmapPixels);

cv::cvtColor(tmp, matrix, cv::COLOR_BGR5652RGB);

}

AndroidBitmap_unlockPixels(env, obj_bitmap); // 解锁

return true;

}

bool MatrixToBitmap(JNIEnv * env, cv::Mat & matrix, jobject obj_bitmap) {

void * bitmapPixels; // 保存图片像素数据

AndroidBitmapInfo bitmapInfo; // 保存图片参数

ASSERT_FALSE( AndroidBitmap_getInfo(env, obj_bitmap, &bitmapInfo) >= 0); // 获取图片参数

ASSERT_FALSE( bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888

|| bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGB_565 ); // 只支持 ARGB_8888 和 RGB_565

ASSERT_FALSE( matrix.dims == 2

&& bitmapInfo.height == (uint32_t)matrix.rows

&& bitmapInfo.width == (uint32_t)matrix.cols ); // 必须是 2 维矩阵,长宽一致

ASSERT_FALSE( matrix.type() == CV_8UC1 || matrix.type() == CV_8UC3 || matrix.type() == CV_8UC4 );

ASSERT_FALSE( AndroidBitmap_lockPixels(env, obj_bitmap, &bitmapPixels) >= 0 ); // 获取图片像素(锁定内存块)

ASSERT_FALSE( bitmapPixels );

if (bitmapInfo.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {

cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC4, bitmapPixels);

switch (matrix.type()) {

case CV_8UC1: cv::cvtColor(matrix, tmp, cv::COLOR_GRAY2RGBA); break;

case CV_8UC3: cv::cvtColor(matrix, tmp, cv::COLOR_RGB2RGBA); break;

case CV_8UC4: matrix.copyTo(tmp); break;

default: AndroidBitmap_unlockPixels(env, obj_bitmap); return false;

}

} else {

cv::Mat tmp(bitmapInfo.height, bitmapInfo.width, CV_8UC2, bitmapPixels);

switch (matrix.type()) {

case CV_8UC1: cv::cvtColor(matrix, tmp, cv::COLOR_GRAY2BGR565); break;

case CV_8UC3: cv::cvtColor(matrix, tmp, cv::COLOR_RGB2BGR565); break;

case CV_8UC4: cv::cvtColor(matrix, tmp, cv::COLOR_RGBA2BGR565); break;

default: AndroidBitmap_unlockPixels(env, obj_bitmap); return false;

}

}

AndroidBitmap_unlockPixels(env, obj_bitmap); // 解锁

return true;

}

JNIEXPORT void JNICALL

Java_com_example_MainActivity_JniBitmapExec(JNIEnv * env, jobject /* this */,

jobject obj_bitmap, jobject obj_bitmapOut)

{

cv::Mat matBitmap;

bool ret = BitmapToMatrix(env, obj_bitmap, matBitmap); // Bitmap 转 cv::Mat

if (ret == false) {

return;

}

// 对 mat 进行 opencv 处理

ret = MatrixToBitmap(env, matBitmap, obj_bitmapOut); // Bitmap 转 cv::Mat

if (ret == false) {

return;

}

}

在建立临时 cv::Mat 时,可以通过传递的地址,访问地址进行读取,或者访问地址进行覆写。

如此可以实现建立 cv::Mat 或者保存到 bitmap 中。

只是注意不同图片下的,格式转换问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。