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