Ber12345
Ber12345

Reputation: 99

Passing a bitmap from android camera to C++ with jni

I have an application on which the user takes a photograph, and this gets returned to the java method in the form of a Bitmap bitmap. I want to pass this bitmap to a C++ function to do some OpenCV processing, as soon as it's been taken.

I'm having trouble finding the right data format to pass the bitmap into the method. I've tried passing the bitmap as a jobect parameter, but it didn't work.

Here is my jni method that i want to pass the bitmap into:

JNIEXPORT jintArray JNICALL Java_com_example_user_digitrecognition_MainActivity_generateAssets(
    JNIEnv *env, jobject thiz, jobject assetManager) {

Upvotes: 1

Views: 2897

Answers (1)

Non-maskable Interrupt
Non-maskable Interrupt

Reputation: 3911

To access pixel buffer of Bitmap from jni, you can call getPixels:

  • NewByteArray an byte[] object (only needed to do once and GlobalRef/reused)
  • FindClass/GetMethodID/CallVoidMethod to invoke the getPixels from c/c++
  • GetByteArrayRegion to map the java byte[] to c buffer.

You can check JNI functions here

Or otherwise, manage the byte[] pixel buffer on Java side, and pass byte[] (and image format/dimension) to jni instead of Bitmap object. For example:

JNIEXPORT jintArray JNICALL Java_com_example_user_digitrecognition_jniFacility_handleFrame(
    JNIEnv *env, jobject self, jobject pixels, jint width, jint height, jint format) {
    ...
}

Since you said you got the Bitmap, to pass bitmap to jni:

pixels = new byte[width * height * 4]; // assume RGBA, do once only
...
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
handleFrame(pixels, bitmap.getWidth(), bitmap.getHeight());

For best performance (and live recording), you may want to use ImageReader and work with YUV image instead.


By the way, opencv accept ImageFormat.YUV_420_888 if you are getting frames by ImageReader. And you probably want to resize and just use the luminance channel for most processing.

Upvotes: 3

Related Questions