I created a drawing application where I allow the user to draw and save the image for subsequent reloading in order to continue drawing. Essentially, I am transferring the drawing as a bitmap to the JNI level I want to save, and the same thing to load the previous drawing.
I use OpenCv to write and read to a png file.
I notice something strange in terms of image transparency. Does transparency seem to be calculated against black on OpenCv? See attached images containing transparencies.
Fix transparency by passing int array to native code, color conversion is not required:
Dark transparency, passing the Bitmap object to its own code, color conversion is required:
What can happen?
Saving an image using its own Bitmap tags to obtain pixels:
if ((error = AndroidBitmap_getInfo(pEnv, jbitmap, &info)) < 0) { LOGE("AndroidBitmap_getInfo() failed! error:%d",error); } if (0 == error) { if ((error = AndroidBitmap_lockPixels(pEnv, jbitmap, &pixels)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", error); } } if (0 == error) { if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) { LOGI("ANDROID_BITMAP_FORMAT_RGBA_8888"); } else { LOGI("ANDROID_BITMAP_FORMAT %d",info.format); } Mat bgra(info.height, info.width, CV_8UC4, pixels); Mat image; //bgra.copyTo(image); // fix pixel order RGBA -> BGRA cvtColor(bgra, image, COLOR_RGBA2BGRA); vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(3); // save image if (!imwrite(filePath, image, compression_params)) { LOGE("saveImage() -> Error saving image!"); error = -7; } // release locked pixels AndroidBitmap_unlockPixels(pEnv, jbitmap); }
Saving an image using int int array methods
JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_saveImageRaw (JNIEnv *pEnv, jobject obj, jstring jFilePath, jintArray jbgra, jint options, jint compression) { jint* _bgra = pEnv->GetIntArrayElements(jbgra, 0); const char *filePath = pEnv->GetStringUTFChars(jFilePath, 0); if (NULL != filePath) { Mat image; Mat bgra(outputHeight, outputWidth, CV_8UC4, (unsigned char *)_bgra); bgra.copyTo(image); if (0 == options) {
Update 05/25/12:
After a little research, I found out that this problem does not occur if I get an array of int pixels from a bitmap and pass it directly to JNI, unlike what I am doing now, which transfers the entire bitmap to JNI then get the pixels and use cvtColor
to convert pixels properly. Am I using the correct pixel transform?