如何在本机代码中从RGBA缓冲区创建Android位图?

时间:2014-06-06 06:23:28

标签: android performance android-ndk java-native-interface

我将BMP作为RGBA缓冲区(我能够将其作为BMP保存在本机代码中并将其视为.bmp图像),我需要将其从本机代码传递给android。我找到了类似的问题和答案,这是其中一个解决方案:

  1. 在android
  2. 中创建android位图对象
  3. 将其传递给本机代码
  4. 以原生代码设置像素缓冲区
  5. 将位图返回到android端
  6. 这不适合我,因为:

    1. 像素数组是使用本机代码创建的
    2. 如果我在android端创建指定的宽度和高度,这会让android分配第二个缓冲区并且它不好,因为我每秒会有24个位图(流式视频)。
    3. 我需要像这样的人:

      1. 从本机代码传递缓冲区和Bitmap.createFromBuffer(缓冲区缓冲区,int宽度,int高度,int格式)
      2. 在本机代码中创建android位图对象,设置像素缓冲区并返回到android
      3. 有任何建议/想法吗?

1 个答案:

答案 0 :(得分:1)

如果你想从本机代码创建java Bitmap对象,你应该这样做:

在本机代码中读取缓冲区,然后将bufer中的每个像素应用于argb格式,如果你有rgba,你可以这样做:

int a = 0xFF & yourPixelInt;
int r = 0xFF & yourPixelInt >> 24;
int g = 0xFF & yourPixelInt >> 16;
int b = 0xFF & yourPixelInt >> 8;
unsigned int newPixel = (a << 24) | (r << 16) | (g << 8) | (b)

为所有像素执行此操作以将其从rgba转换为argb,之后您可以从本机代码创建java Bitmap:

jint* bytes = env->GetIntArrayElements( array, NULL );
if (bytes != NULL) {
    memcpy(bytes, buffer, origBufferSize * sizeof (unsigned int));
    env->ReleaseIntArrayElements( array, bytes, 0 );
}

jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
jmethodID methodid = env->GetStaticMethodID(bitmapClass, "createBitmap", "([IIIIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");

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

jobject java_bitmap = env->CallStaticObjectMethod(bitmapClass, methodid, array, 0, bitmapwidth, bitmapwidth, bitmapheight, argb8888Obj);

不要忘记释放对象以避免内存泄漏

env->DeleteLocalRef(array);
env->DeleteLocalRef(bitmapClass);
env->DeleteLocalRef(bitmapConfig);
env->DeleteLocalRef(argb8888Obj);