【问题标题】:How to create Android bitmap from RGBA buffer in native code?如何在本机代码中从 RGBA 缓冲区创建 Android 位图?
【发布时间】:2014-07-27 08:24:59
【问题描述】:

我将 BMP 作为 RGBA 缓冲区(我可以将其保存为原生代码中的 BMP 并将其查看为 .bmp 图像),我需要将其从原生代码传递给 android。我发现了类似的问题和答案,这是解决方案之一:

  1. 在 android 中创建 android 位图对象
  2. 将其传递给本机代码
  3. 在本机代码中设置像素缓冲区
  4. 将位图返回到安卓端

这不适合我,因为:

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

我需要这样的东西:

  1. 从本机代码和 Bitmap.createFromBuffer(Buffer buffer, int width, int height, int format) 传递 Buffer
  2. 在本机代码中创建 android 位图对象,设置像素缓冲区并返回到 android

有什么建议/想法吗?

【问题讨论】:

  • 如何将其以.jpg格式保存到SD卡并再次读取?
  • 这可能是一个解决方案,但我不确定移动设备是否适合为流式视频保存帧
  • 通常流式视频涉及 YUV 缓冲区。 YUV 到 RGBA 的转换非常昂贵(与软件 h264 解码器使用的 CPU 资源顺序相同,比运行硬件解码器所花费的要多得多)。使用渲染脚本或 OpenGL 可以改进 YUV 到 RGB 的转换。

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


【解决方案1】:

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

在本机代码中读取你的缓冲区,然后将缓冲区中的每个像素应用到 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多