在Android NDK中有一个名为JNI Graphics的库。那是什么?我可以使用它来加载带有C / C ++的OpenGL ES图像吗?
答案 0 :(得分:19)
jnigraphics
库可用于从android.bitmap.Graphics
类(当然是Java)访问C / C ++中的位图缓冲区。
NDK documentation以及bitmap.h
header docs简要提到了这一点。
它可用于加载图像,例如使用C / C ++中的OpenGL ES,但是您必须做一些工作才能将jobject
交给该库,以便它可以直接访问缓冲区。您可以通过glTexImage2D()
将该缓冲区传递给OpenGL。
首先,您需要一个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
原生方法看起来像这样:
#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
}
请记住,在完成像素缓冲区后,您应该调用AndroidBitmap_unlockPixels()
,并且此示例根本不会检查错误。
更新Sid Datta的问题:您可以通过将其添加到上述选项来确保输出图像格式符合您的预期:
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
有一种情况,输出图像仍然在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;
}