在图像处理SDK像安卓平台转化时,因为使用C/C++开发,所有对外接口需要封装成JNI接口,图像数据的传递可以采用裸数据的形式,直接将传回图像像素值数组,但是也会遇到需要传回bitmap,这时候可以采用两种方案。
一、Java预先creatBitmap,然后将jobject bitmap作为JNI接口的参数,传给JNI层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | AndroidBitmapInfo info; int result = AndroidBitmap_getInfo(env, bitmap, &info);//获取java层创建的bitmap图像信息 if (result != ANDROID_BITMAP_RESULT_SUCCESS) { LOGD("AndroidBitmap_getInfo failed, result: %d", result); return (jint)ERROR_INVALID_IMAGE; } LOGD("bitmap width: %d, height: %d, format: %d, stride: %d", info.width, info.height, info.format, info.stride); unsigned char *srcData = NULL; AndroidBitmap_lockPixels(env, bitmap, (void**)&srcData);//锁定图像像素 for(int i=0;i<info.width*info.height;i++) { srcData[4*i] = imgData[3*i]; //这里的imgData指的就是存放了像素值的数据 srcData[4*i+1] = imgData[3*i+1]; srcData[4*i+2] = imgData[3*i+2]; srcData[4*i+3] = (unsigned char)255; } AndroidBitmap_unlockPixels(env, bitmap);//释放图像像素 |
该方案需要java层预先创建好一个bitmap,但实际情况可能是java层在调用接口前并不知道要创建多大尺寸的bitmap,这时可采用下面的方法。
二、JNI层回调Java的Bitmap类与方法creatBitmap,然后将jobject bitmap传出(比如直接return)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | jclass bitmapCls = env->FindClass("android/graphics/Bitmap"); jmethodID createBitmapFunction = env->GetStaticMethodID(bitmapCls,"createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); jstring configName = env->NewStringUTF("ARGB_8888"); jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config"); jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID( bitmapConfigClass, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;"); jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass, valueOfBitmapConfigFunction,configName); jobject bitmap = env->CallStaticObjectMethod(bitmapCls, createBitmapFunction, nOutWidth, nOutHeight, bitmapConfig); unsigned char *resultBitmapPixels = NULL; int ret; if ((ret = AndroidBitmap_lockPixels(env, bitmap, (void**)&resultBitmapPixels)) < 0) { LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret); } int pixelsCount = nOutWidth * nOutHeight * 4; for(int i=0;i<nOutWidth*nOutHeight;i++) { resultBitmapPixels[4*i] = imgData[3*i]; resultBitmapPixels[4*i+1] = imgData[3*i+1]; resultBitmapPixels[4*i+2] = imgData[3*i+2]; resultBitmapPixels[4*i+3] = (unsigned char)255; } AndroidBitmap_unlockPixels(env, bitmap);//最终得到的就是bitmap |
ps:编译时Android.mk中LOCAL_LDLIBS := -llog -ljnigraphics,使用AndroidBitmap需要-ljnigraphics