什么是JNI Graphics或如何使用它?

doj*_*rdi 10 java-native-interface android opengl-es android-ndk

在Android NDK中有一个名为JNI Graphics的库.那是什么?我可以用它来加载带有C/C++的OpenGL ES图像吗?

Dan*_*ler 20

jnigraphics库可用于从android.bitmap.Graphics类中访问C/C++中的位图缓冲区(当然,在Java中).

NDK文档中简要提到了它,以及bitmap.h 标题文档.

它可以用于在C/C++中加载例如OpenGL ES的图像,但是你必须做一些工作来jobject交给该库,这样它才能让你直接访问缓冲区.您可以通过该缓冲区传递给OpenGL glTexImage2D().

首先,您需要一个Java Bitmap对象,您可以获取并传递给您的本机方法,如下所示:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
       ...

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                                             R.drawable.myimage, options);

MyJniMethod(bitmap); // Should be static in this example
Run Code Online (Sandbox Code Playgroud)

该本机方法可能如下所示:

#include <android/bitmap.h>

void MyJniMethod(JNIEnv *env, jobject obj, jobject bitmap) {
AndroidBitmapInfo  info;
uint32_t          *pixels;
int                ret;

AndroidBitmap_getInfo(env, bitmap, &info);

if(info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
  LOGE("Bitmap format is not RGBA_8888!");
  return false;
}

AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels));

// Now you can use the pixel array 'pixels', which is in RGBA format

}
Run Code Online (Sandbox Code Playgroud)

请记住,AndroidBitmap_unlockPixels()当您完成像素缓冲区时应该调用,并且此示例根本不检查错误.


更新Sid Datta的问题:您可以通过将其添加到上面的选项来确保输出图像格式符合您的预期:

options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Run Code Online (Sandbox Code Playgroud)

有一种情况是输出图像仍然在JNI中以未知格式结束.这似乎只发生在GIF上.调用后BitmapFactory.decodeResource(),您可以根据需要将图像转换为正确的格式:

if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
    Bitmap reformatted_bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
    bitmap.recycle(); /* reduce memory load in app w/o waiting for GC */
    bitmap = reformatted_bitmap;
}
Run Code Online (Sandbox Code Playgroud)