Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

android - 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 that to load Images for OpenGL ES with C/C++?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...