What is JNI Graphics or how to use it?
In the Android NDK there is a library named JNI Graphics. What is that? Can I use tha开发者_Go百科t to load Images for OpenGL ES with C/C++?
The jnigraphics
library can be used to access bitmap buffers in C/C++ from the android.bitmap.Graphics
class (in Java, of course).
It's briefly mentioned in the NDK documentation, as well as the bitmap.h
header docs.
It can be used to load images for e.g. OpenGL ES in C/C++, but you have to do some work to hand a jobject
to that library so it can give you direct access to a buffer. You can pass that buffer to OpenGL via glTexImage2D()
.
First, you need a Java Bitmap
object, which you can acquire and pass to your native method like this:
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
That native method can look something like this:
#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
}
Keep in mind you should call AndroidBitmap_unlockPixels()
when you are done with the pixel buffer, and that this example doesn't check for errors at all.
Update for Sid Datta's question: You can ensure that the output image format is what you're expecting by adding this to options above:
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
There is one case where the output image will still end up with an unknown format in JNI. This seems to happen only with GIFs. After calling BitmapFactory.decodeResource()
, you can convert the image to the proper format if necessary:
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;
}
精彩评论