1 #define LOG_TAG "org.opencv.android.Utils" 2 #include "common.h" 3 4 #include "opencv2/core.hpp" 5 #include "opencv2/imgproc.hpp" 6 7 #ifdef __ANDROID__ 8 #include <android/bitmap.h> 9 10 using namespace cv; 11 12 extern "C" { 13 14 /* 15 * Class: org_opencv_android_Utils 16 * Method: void nBitmapToMat2(Bitmap b, long m_addr, boolean unPremultiplyAlpha) 17 */ 18 19 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat2 20 (JNIEnv * env, jclass, jobject bitmap, jlong m_addr, jboolean needUnPremultiplyAlpha); 21 22 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat2 23 (JNIEnv * env, jclass, jobject bitmap, jlong m_addr, jboolean needUnPremultiplyAlpha) 24 { 25 AndroidBitmapInfo info; 26 void* pixels = 0; 27 Mat& dst = *((Mat*)m_addr); 28 29 try { 30 LOGD("nBitmapToMat"); 31 CV_Assert( AndroidBitmap_getInfo(env, bitmap, &info) >= 0 ); 32 CV_Assert( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 || 33 info.format == ANDROID_BITMAP_FORMAT_RGB_565 ); 34 CV_Assert( AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 ); 35 CV_Assert( pixels ); 36 dst.create(info.height, info.width, CV_8UC4); 37 if( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ) 38 { 39 LOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4"); 40 Mat tmp(info.height, info.width, CV_8UC4, pixels); 41 if(needUnPremultiplyAlpha) cvtColor(tmp, dst, COLOR_mRGBA2RGBA); 42 else tmp.copyTo(dst); 43 } else { 44 // info.format == ANDROID_BITMAP_FORMAT_RGB_565 45 LOGD("nBitmapToMat: RGB_565 -> CV_8UC4"); 46 Mat tmp(info.height, info.width, CV_8UC2, pixels); 47 cvtColor(tmp, dst, COLOR_BGR5652RGBA); 48 } 49 AndroidBitmap_unlockPixels(env, bitmap); 50 return; 51 } catch(const cv::Exception& e) { 52 AndroidBitmap_unlockPixels(env, bitmap); 53 LOGE("nBitmapToMat catched cv::Exception: %s", e.what()); 54 jclass je = env->FindClass("org/opencv/core/CvException"); 55 if(!je) je = env->FindClass("java/lang/Exception"); 56 env->ThrowNew(je, e.what()); 57 return; 58 } catch (...) { 59 AndroidBitmap_unlockPixels(env, bitmap); 60 LOGE("nBitmapToMat catched unknown exception (...)"); 61 jclass je = env->FindClass("java/lang/Exception"); 62 env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}"); 63 return; 64 } 65 } 66 67 // old signature is left for binary compatibility with 2.4.0 & 2.4.1, to removed in 2.5 68 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat 69 (JNIEnv * env, jclass, jobject bitmap, jlong m_addr); 70 71 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat 72 (JNIEnv * env, jclass, jobject bitmap, jlong m_addr) 73 { 74 Java_org_opencv_android_Utils_nBitmapToMat2(env, 0, bitmap, m_addr, false); 75 } 76 77 /* 78 * Class: org_opencv_android_Utils 79 * Method: void nMatToBitmap2(long m_addr, Bitmap b, boolean premultiplyAlpha) 80 */ 81 82 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap2 83 (JNIEnv * env, jclass, jlong m_addr, jobject bitmap, jboolean needPremultiplyAlpha); 84 85 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap2 86 (JNIEnv * env, jclass, jlong m_addr, jobject bitmap, jboolean needPremultiplyAlpha) 87 { 88 AndroidBitmapInfo info; 89 void* pixels = 0; 90 Mat& src = *((Mat*)m_addr); 91 92 try { 93 LOGD("nMatToBitmap"); 94 CV_Assert( AndroidBitmap_getInfo(env, bitmap, &info) >= 0 ); 95 CV_Assert( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 || 96 info.format == ANDROID_BITMAP_FORMAT_RGB_565 ); 97 CV_Assert( src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols ); 98 CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4 ); 99 CV_Assert( AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 ); 100 CV_Assert( pixels ); 101 if( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ) 102 { 103 Mat tmp(info.height, info.width, CV_8UC4, pixels); 104 if(src.type() == CV_8UC1) 105 { 106 LOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888"); 107 cvtColor(src, tmp, COLOR_GRAY2RGBA); 108 } else if(src.type() == CV_8UC3){ 109 LOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888"); 110 cvtColor(src, tmp, COLOR_RGB2RGBA); 111 } else if(src.type() == CV_8UC4){ 112 LOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888"); 113 if(needPremultiplyAlpha) cvtColor(src, tmp, COLOR_RGBA2mRGBA); 114 else src.copyTo(tmp); 115 } 116 } else { 117 // info.format == ANDROID_BITMAP_FORMAT_RGB_565 118 Mat tmp(info.height, info.width, CV_8UC2, pixels); 119 if(src.type() == CV_8UC1) 120 { 121 LOGD("nMatToBitmap: CV_8UC1 -> RGB_565"); 122 cvtColor(src, tmp, COLOR_GRAY2BGR565); 123 } else if(src.type() == CV_8UC3){ 124 LOGD("nMatToBitmap: CV_8UC3 -> RGB_565"); 125 cvtColor(src, tmp, COLOR_RGB2BGR565); 126 } else if(src.type() == CV_8UC4){ 127 LOGD("nMatToBitmap: CV_8UC4 -> RGB_565"); 128 cvtColor(src, tmp, COLOR_RGBA2BGR565); 129 } 130 } 131 AndroidBitmap_unlockPixels(env, bitmap); 132 return; 133 } catch(const cv::Exception& e) { 134 AndroidBitmap_unlockPixels(env, bitmap); 135 LOGE("nMatToBitmap catched cv::Exception: %s", e.what()); 136 jclass je = env->FindClass("org/opencv/core/CvException"); 137 if(!je) je = env->FindClass("java/lang/Exception"); 138 env->ThrowNew(je, e.what()); 139 return; 140 } catch (...) { 141 AndroidBitmap_unlockPixels(env, bitmap); 142 LOGE("nMatToBitmap catched unknown exception (...)"); 143 jclass je = env->FindClass("java/lang/Exception"); 144 env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}"); 145 return; 146 } 147 } 148 149 // old signature is left for binary compatibility with 2.4.0 & 2.4.1, to removed in 2.5 150 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap 151 (JNIEnv * env, jclass, jlong m_addr, jobject bitmap); 152 153 JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap 154 (JNIEnv * env, jclass, jlong m_addr, jobject bitmap) 155 { 156 Java_org_opencv_android_Utils_nMatToBitmap2(env, 0, m_addr, bitmap, false); 157 } 158 159 } // extern "C" 160 161 #endif //__ANDROID__ 162