官方文档 https://docs.opencv.org/java/3.0.0
Mat 保存了图像的一个多维矩阵;
Bitmap知识点
ANDROID_BITMAP_FORMAT_RGBA_8888
每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位
ANDROID_BITMAP_FORMAT_RGB_565
每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
Bitmap.Config ARGB_4444:
每个像素占四位,即A=4,R=4,G=4,B=4,
那么一个像素点占4+4+4+4=16位(过时弃用)~~
Bitmap.Config ALPHA_8:
每个像素占四位,只有透明度,没有颜色。
对应CV中的关系
Bitmap.Config ALPHA_8 = 8UC1 = 8
8:8位
U:unsigned char
C:channel
1:数量
Bitmap.Config RGB_565 = 8UC2 = 16
Bitmap.Config RGB_8888 = 8UC4 = 16
mat2bitmap
void MatToBitmap(JNIEnv *env, Mat &mat, jobject &bitmap) {
bool needPremultiplyAlpha = false;
AndroidBitmapInfo info;
void *pixels = 0;
Mat &src = mat;
try {
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) {
printf("%s RGBA", __FUNCTION__);
Mat tmp(info.height, info.width, CV_8UC4, pixels);
if (src.type() == CV_8UC1) {
cvtColor(src, tmp, COLOR_GRAY2RGBA);
} else if (src.type() == CV_8UC3) {
cvtColor(src, tmp, COLOR_RGB2RGBA);
} else if (src.type() == CV_8UC4) {
if (needPremultiplyAlpha)
cvtColor(src, tmp, COLOR_RGBA2mRGBA);
else
src.copyTo(tmp);
}
} else {
printf("%s BGR565", __FUNCTION__);
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
Mat tmp(info.height, info.width, CV_8UC2, pixels);
if (src.type() == CV_8UC1) {
cvtColor(src, tmp, COLOR_GRAY2BGR565);
} else if (src.type() == CV_8UC3) {
cvtColor(src, tmp, COLOR_RGB2BGR565);
} else if (src.type() == CV_8UC4) {
cvtColor(src, tmp, COLOR_RGBA2BGR565);
}
}
AndroidBitmap_unlockPixels(env, bitmap);
return;
} catch (const cv::Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass("org/opencv/core/CvException");
if (!je) je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, e.what());
return;
} catch (...) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
return;
}
}
bitmap2mat
void Detect::BitmapToMat(JNIEnv *env, jobject &bitmap, Mat &mat) {
bool needUnPremultiplyAlpha = true;
AndroidBitmapInfo info;
void *pixels = nullptr;
Mat &dst = mat;
try {
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) {
Mat tmp(info.height, info.width, CV_8UC4, pixels);
if (needUnPremultiplyAlpha)
cvtColor(tmp, dst, COLOR_RGBA2BGR);
// cvtColor(tmp, dst, COLOR_mRGBA2RGBA);
else tmp.copyTo(dst);
} else {
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
Mat tmp(info.height, info.width, CV_8UC2, pixels);
// cvtColor(tmp, dst, COLOR_BGR5652RGBA);
cvtColor(tmp, dst, COLOR_RGBA2BGR);
}
AndroidBitmap_unlockPixels(env, bitmap);
return;
} catch (const cv::Exception &e) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass("org/opencv/core/CvException");
if (!je) je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, e.what());
printf("%s %s \n", __FUNCTION__, e.err.c_str());
return;
} catch (...) {
AndroidBitmap_unlockPixels(env, bitmap);
jclass je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
return;
}
}
网友评论