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
Java_org_opencv_android_Utils_nBitmapToMat2(JNIEnv * env,jclass,jobject bitmap,jlong m_addr,jboolean needUnPremultiplyAlpha)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
Java_org_opencv_android_Utils_nBitmapToMat(JNIEnv * env,jclass,jobject bitmap,jlong m_addr)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
Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv * env,jclass,jlong m_addr,jobject bitmap,jboolean needPremultiplyAlpha)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
Java_org_opencv_android_Utils_nMatToBitmap(JNIEnv * env,jclass,jlong m_addr,jobject bitmap)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