在 JNI 環(huán)境下 使用 Opencv 處理圖片 第一步,CV::Mat 互轉(zhuǎn) Bitmap。
- 調(diào)用演示
JNIEXPORT void imageGrayscale(JNIEnv *env, jclass thiz, jobject bitmap) {
cv::Mat srcMat, dstMat;
BitmapToMat(env, bitmap, srcMat);
dstMat = image_grayscale(srcMat);
MatToBitmap(env, dstMat, bitmap);
}
- Bitmap -> CV::Mat (GRAY/RGB/RGBA)
void BitmapToMat2(JNIEnv *env, jobject& bitmap, cv::Mat& mat, jboolean needUnPremultiplyAlpha) {
AndroidBitmapInfo info; //保存圖像參數(shù)
void *pixels = 0; //保存圖像數(shù)據(jù)
cv::Mat &dst = mat;
try {
//LOGD("nBitmapToMat");
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) {
//LOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4");
cv::Mat tmp(info.height, info.width, CV_8UC4, pixels);
if (needUnPremultiplyAlpha) {
cv::cvtColor(tmp, dst, cv::COLOR_mRGBA2RGBA);
}
else {
tmp.copyTo(dst);
}
}
else {
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
//LOGD("nBitmapToMat: RGB_565 -> CV_8UC4");
cv::Mat tmp(info.height, info.width, CV_8UC2, pixels);
cv::cvtColor(tmp, dst, cv::COLOR_BGR5652RGBA);
}
AndroidBitmap_unlockPixels(env, bitmap);
return;
}
catch (const cv::Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
LOGE("nBitmapToMat catched cv::Exception: %s", e.what());
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, e.what());
env->DeleteLocalRef(je);
return;
}
catch (...) {
AndroidBitmap_unlockPixels(env, bitmap);
LOGE("nBitmapToMat catched unknown exception (...)");
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
env->DeleteLocalRef(je);
return;
}
}
void BitmapToMat(JNIEnv *env, jobject& bitmap, cv::Mat& mat) {
BitmapToMat2(env, bitmap, mat, false);
}
- CV::Mat -> Bitmap
void MatToBitmap2(JNIEnv *env, cv::Mat& mat, jobject& bitmap, jboolean needPremultiplyAlpha) {
AndroidBitmapInfo info;
void *pixels = 0;
cv::Mat &src = mat;
try {
//LOGD("nMatToBitmap");
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) {
cv::Mat tmp(info.height, info.width, CV_8UC4, pixels);
if (src.type() == CV_8UC1) {
//LOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888");
cv::cvtColor(src, tmp, cv::COLOR_GRAY2RGBA);
}
else if (src.type() == CV_8UC3) {
//LOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888");
cv::cvtColor(src, tmp, cv::COLOR_RGB2RGBA);
}
else if (src.type() == CV_8UC4) {
//LOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888");
if (needPremultiplyAlpha) {
cv::cvtColor(src, tmp, cv::COLOR_RGBA2mRGBA);
}
else {
src.copyTo(tmp);
}
}
}
else {
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
cv::Mat tmp(info.height, info.width, CV_8UC2, pixels);
if (src.type() == CV_8UC1) {
//LOGD("nMatToBitmap: CV_8UC1 -> RGB_565");
cv::cvtColor(src, tmp, cv::COLOR_GRAY2BGR565);
}
else if (src.type() == CV_8UC3) {
//LOGD("nMatToBitmap: CV_8UC3 -> RGB_565");
cv::cvtColor(src, tmp, cv::COLOR_RGB2BGR565);
}
else if (src.type() == CV_8UC4) {
//LOGD("nMatToBitmap: CV_8UC4 -> RGB_565");
cv::cvtColor(src, tmp, cv::COLOR_RGBA2BGR565);
}
}
AndroidBitmap_unlockPixels(env, bitmap);
return;
}
catch (const cv::Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
LOGE("nMatToBitmap catched cv::Exception: %s", e.what());
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, e.what());
env->DeleteLocalRef(je);
return;
}
catch (...) {
AndroidBitmap_unlockPixels(env, bitmap);
LOGE("nMatToBitmap catched unknown exception (...)");
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
env->DeleteLocalRef(je);
return;
}
}
void MatToBitmap(JNIEnv *env, cv::Mat& mat, jobject& bitmap) {
MatToBitmap2(env, mat, bitmap, false);
}
- Log 打印
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "ImageProc-error", __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "ImageProc-debug", __VA_ARGS__)