Home Converting bitmap to Opencv::Mat in JNI
Reply: 1

Converting bitmap to Opencv::Mat in JNI

Jun Fang
Jun Fang Published in 2017-03-06 10:48:24Z

I am building a image processing project in Android. I capture bitmap pictures through camera, and feed it to the opencv C++ function through JNI.

Firstly, I test my opencv c++ function using saved bitmap pictures (PNG format), and it it successful.

  // in Android, save bitmap
  Bitmap bmp = YUV_420_888_toRGB(img,img.getWidth(),img.getHeight());
  try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    Log.e(TAG,"saved successfully.)");

                } catch (FileNotFoundException e) {
                    Log.d(TAG, "File not found: " + e.getMessage());
                } catch (IOException e) {
                    Log.d(TAG, "Error accessing file: " + e.getMessage());

  // in opencv c++ function
  Mat im = imread("/Users/Jun/Downloads/20170227/P9/1488167433596_frame.PNG");

  // processing im

Then i feed each captured bitmap picture to the same opencv c++ function. However, the detected result is totally different. I think there must be some errors when converting bitmap in Java to opencv mat in C++ through JNI. Please find the converting codes below:

   //Java side:
   public static int[] detector(Bitmap bitmap) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    int []pixels = new int[w*h];

   return detect(pixels,w,h);


private static native int[] detect(int pixels[],int w,int h);

  // c++ side:
  JNIEXPORT jintArray JNICALL     Java_com_example_jun_helloworld_JNIUtils_detect(JNIEnv *env, jclass cls, jintArray buf, jint w, jint h) {
jint* cbuf = env->GetIntArrayElements(buf, false);
if (cbuf == NULL) {
    return NULL;
Mat im(h, w, CV_8UC4, (unsigned char *) cbuf);

// processing im

The two "im"s should be different. Can someone tell me what's wrong in the converting? thanks.

mko Reply to 2017-03-08 19:05:56Z

In your code, you cast int pointer to char pointer. So, you will change the way your code treats your data.

Take a look here:

#include <stdio.h>

int main() {

    // what you have in the code is array of ints
    int iarray[5] = {1, 2, 3, 4, 5};
    int *iarray_ptr = iarray;

    // and you cast int pointer to char pointer
    char *carray_ptr = (char *) iarray_ptr;

    // so, you simply skip some values because of
    // pointer aritmetics; your data are shifted
    for(int i=0;i<5;i++) {
        printf("int: %p, char %p\n", iarray_ptr + i, carray_ptr + i);

    // you can always do something like this
    char carray2[5];
    for(int p=0;p<5;p++) {
        // you can loose precision here!
        carray2[p] = (char) iarray[p];

    // and then, you can simply pass &carray2 to
    // to your code

If you run the code, you can clearly see what will be the difference in pointer arithmetics:

int: 0x7fff51d859f0, char 0x7fff51d859f0
int: 0x7fff51d859f4, char 0x7fff51d859f1
int: 0x7fff51d859f8, char 0x7fff51d859f2
int: 0x7fff51d859fc, char 0x7fff51d859f3
int: 0x7fff51d85a00, char 0x7fff51d859f4

After casting to char *, you will simply "scatter" your data.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.319061 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO