I m 测试使用 OpenCv 操作 JNI 层比特马普像素的性能。
Two options:
1. Pass array of integers, manipulate the pixels and write pixels back to Bitmap. [41ms]
2. Pass the entire Bitmap. [35ms]
我注意到,通过Bitmap的速度比通过像素阵列和将阵列分配到Bitmap要快大约5米。
问题在于使用选项 2 I m 来清除蓝色颜色, 并获得橙色的颜色来代替我所期望的蓝色。 图像是 ARGB, 它似乎已经变成 RGBA 了? 问题是什么?
Method 1:
Java
Bitmap out = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int[] rgba = new int[width*height];
mSmasher.loadImage(imagePath, rgba, 0);
out.setPixels(rgba, 0, width, 0, 0, width, height);
JNI
JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_loadImage
(JNIEnv *pEnv, jobject obj, jstring jFilePath, jintArray jbgra, jint options)
{
jint* _bgra = pEnv->GetIntArrayElements(jbgra, 0);
const char *filePath = pEnv->GetStringUTFChars(jFilePath, 0);
if (NULL != filePath)
{
// init our output image
Mat bgra(outputHeight, outputWidth, CV_8UC4, (unsigned char *)_bgra);
// bgra image manipulations
}
pEnv->ReleaseIntArrayElements(jbgra, _bgra, 0);
pEnv->ReleaseStringUTFChars(jFilePath, filePath);
}
<强 > 方法2: 强 >
JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_getLayersBitmap
(JNIEnv *pEnv, jobject obj, jobject bitmap)
{
int ret;
AndroidBitmapInfo info;
void* pixels = 0;
if ((ret = AndroidBitmap_getInfo(pEnv, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 )
{
LOGE("Bitmap format is not RGBA_8888!");
return;
}
if ((ret = AndroidBitmap_lockPixels(pEnv, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
// init our output image
Mat mbgra(info.height, info.width, CV_8UC4, pixels);
mLayers[0].copyTo(mbgra);
AndroidBitmap_unlockPixels(pEnv, bitmap);
}
Solution 05/23:
The problem was that when using an array of integers and passing it to the JNI the byte order is changed from ARGB (java) to BGRA(native). This was fine for working with the pixels. However passing the actual Bitmap object when locking the pixels the byte order didn t change so it required to change it after modifying the pixel data.
cvtColor(mbgra, mbgra, COLOR_BGR2RGBA, 4);