Что такое графика JNI или как ее использовать?

В Android NDK есть библиотека JNI Graphics. Это что? Могу ли я использовать это для загрузки изображений для OpenGL ES с C/C++?


person dojordi    schedule 09.04.2011    source источник


Ответы (1)


Библиотека jnigraphics может использоваться для доступа к буферам растровых изображений в C/C++ из класса android.bitmap.Graphics (конечно, в Java).

Это кратко упоминается в документации NDK, а также в bitmap.h документы заголовка.

Его можно использовать для загрузки изображений, например. OpenGL ES в C/C++, но вам нужно проделать некоторую работу, чтобы передать 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

Этот нативный метод может выглядеть примерно так:

#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(), когда закончите с пиксельным буфером, и что этот пример вообще не проверяет наличие ошибок.


Обновление для вопроса Сида Датты: вы можете убедиться, что формат выходного изображения соответствует ожидаемому, добавив это к параметрам выше:

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;
}
person Daniel Schuler    schedule 22.04.2011
comment
Гарантируется ли, что Pixel упакован в формате RGBA во всех версиях Android? - person Sid Datta; 24.05.2013
comment
Можно ли прочитать растровое изображение из кода Java, если оно заблокировано из собственного кода? - person bk138; 04.10.2019
comment
@ bk138 - да, блокировка здесь гарантирует, что сборщик мусора Java не освободит эту память, если он больше не увидит на нее ссылок Java. Он должен был называться «увеличить референскаунт» или что-то в этом роде. - person Daniel Schuler; 05.10.2019