Home | History | Annotate | Download | only in cpp
      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