JNI创建Bitmap

背景

JNI c++层需要从byte[]数组,pixels创建成jbitmap格式

Show me the Code

方法一: 速度较慢


    int _width = image.mWidth;
    int _height = image.mHeight;
    unsigned char *bitmap = image.mPixelData;

    jclass bitmapConfig = env->FindClass("android/graphics/Bitmap$Config");
    jfieldID rgba8888FieldID = env->GetStaticFieldID(bitmapConfig, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
    jobject rgba8888Obj = env->GetStaticObjectField(bitmapConfig, rgba8888FieldID);

    jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
    jmethodID createBitmapMethodID = env->GetStaticMethodID(bitmapClass,"createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    jobject newBitmap = env->CallStaticObjectMethod(bitmapClass, createBitmapMethodID, _width, _height, rgba8888Obj);

    jintArray pixels = env->NewIntArray(_width * _height);
    LOGD("start 1");
    for (int i = 0; i < _width * _height; i++)
    {
        unsigned char red = bitmap[i*4];
        unsigned char green = bitmap[i*4 + 1];
        unsigned char blue = bitmap[i*4 + 2];
        unsigned char alpha = bitmap[i*4 + 3];
        int currentPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
        env->SetIntArrayRegion(pixels, i, 1, &currentPixel);
    }
    LOGD("start 2");

    jmethodID setPixelsMid = env->GetMethodID(bitmapClass, "setPixels", "([IIIIIII)V");
    env->CallVoidMethod(newBitmap, setPixelsMid, pixels, 0, _width, 0, 0, _width, _height);
    LOGD("start 3");

    //newBitmap Format: 1
    AndroidBitmapInfo info;
    AndroidBitmap_getInfo(env, newBitmap ,&info);
    LOGD("newBitmap Format: %d" , info.format);

方法二: 速度较快

    //Bitmap.Config config = Bitmap.Config.valueOf(String configName);
    jstring configName = env->NewStringUTF("ARGB_8888");
    jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config");
    jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID(bitmapConfigClass, "valueOf",
                                                                   "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
    jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass, valueOfBitmapConfigFunction,bitmapConfigClass, configName);

    // Bitmap newBitmap = Bitmap.createBitmap(int width,int height,Bitmap.Config config);
    jclass bitmap = env->FindClass("android/graphics/Bitmap");
    jmethodID createBitmapFunction = env->GetStaticMethodID(bitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    jobject newBitmap = env->CallStaticObjectMethod(bitmap, createBitmapFunction, image.width(), image.height(), bitmapConfig);

    int ret;
    unsigned char *newBitmapPixels;

    if ((ret = AndroidBitmap_lockPixels(env, newBitmap, (void**)&newBitmapPixels)) < 0){
        LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    unsigned char *imgData = image.mPixelData;

    for(int i = 0; i < image.mWidth * image.mHeight ; i++){
        newBitmapPixels[i*4] = imgData[i*4];
        newBitmapPixels[i*4+1] = imgData[i*4 + 1];
        newBitmapPixels[i*4+2] = imgData[i*4 + 2];
        newBitmapPixels[i*4+3] = imgData[i*4 + 3];
    }
    AndroidBitmap_unlockPixels(env, newBitmap);

bug

方法一创建的bitmap格式为1,RGBA_8888,但方法二创建的bitmap格式为6,很奇怪,无法查找.

参考

Android JNI 之 Bitmap 操作

Creating a new Bitmap with Pixel Data in JNI?

你可能感兴趣的:(学习笔记,jni创建,jni创建bitmap,android,bitmap,ndk)