Bitmap NDK processing using blue OpenCv orange?

I am testing performance for managing raster pixels at the JNI level using OpenCv.

Two options:
1. Skip an array of integers, manipulate pixels and write pixels back to the bitmap. [41ms]
2. Skip the entire bitmap. [35ms]

I noticed that it transmits a bitmap about 5 ms faster than it transmits an array of pixels and assigns an array to a bitmap.

The problem is that using option 2, I lose the blue color and get an orange color instead of the blue that I expect. The image is ARGB, and it looks like it's changed to RGBA? What could be the problem?

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); } 

Method 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); } 

Decision 05/23:
The problem was that when using an array of integers and passing it to the JNI, the byte order changes from ARGB (java) to BGRA (native). It was great for working with pixels. However, passing the actual Bitmap object when blocking the pixels did not change the byte order, so it needed to be changed after changing the pixel data.

 cvtColor(mbgra, mbgra, COLOR_BGR2RGBA, 4); 
+4
source share
2 answers

The order of Opencv is BGR, not RGB. I'm going to guess that A is in the right place (or you will see a translucent image), but blue and red will change.

+2
source

In color value, JNI returns as ARGB, and in JAVA - RGBA try this

 alpha = (int) ((color & 0xFF000000) >> 24); blue = (int) ((color & 0xFF0000) >> 16); green = (int)((color & 0x00FF00) >> 8); red = (int) (color & 0x0000FF); blue = blue * alpha / 255; green = green * alpha / 255; red = red * alpha / 255; int tmp = 0; tmp = red; red = blue; blue = tmp; color = ((alpha<< 24) & 0xFF000000) | ((blue<< 16) & 0xFF0000) | ((green << 8) & 0x00FF00) | (red & 0x0000FF); 
+1
source

Source: https://habr.com/ru/post/1413863/


All Articles