Вызов JNI с проблемой Android NDK - PullRequest
2 голосов
/ 03 декабря 2011

У меня есть функция C, которую я вызываю из Java с помощью Android NDK.По сути, он берет данные с камеры и преобразует их из формата YUV в формат RGB.Проблема в том, что я не уверен, какой тип объекта imageOut возвращается, так как в C это просто тип jobject.Вот фрагмент кода, который у меня есть (к сожалению, мне больше нечего идти):

JNIEXPORT void JNICALL Java_com_twothreetwo_zoomplus_ZoomPlus_yuvrgb(JNIEnv *env, jobject obj, jbyteArray imageIn, jint widthIn, jint heightIn, jobject imageOut, jint widthOut, jint heightOut)
{
    LOGI("width is %d; height is %d;",widthIn,heightIn);

    jbyte *cImageIn = (*env)->GetByteArrayElements(env, imageIn, NULL);
    jbyte *cImageOut = (jbyte*)(*env)->GetDirectBufferAddress(env, imageOut);


    unsigned int *rgbs = (unsigned int*)cImageOut;

    int half_widthIn = widthIn >> 1;

      //the end of the luminance data
      int lumEnd = (widthIn * heightIn) >> 1;
      //points to the next luminance value pair
      int lumPtr = 0;
      //points to the next chromiance value pair
      int chrPtr = lumEnd;
      //the end of the current luminance scanline
      int lineEnd = half_widthIn;
      unsigned short *yuvs;
      int x,y;
      for (y=0;y<heightIn;y++) {
        int yPosOut=(y*widthOut) >> 1;
        for (x=0;x<half_widthIn;x++) {
          //read the luminance and chromiance values
          int Y1 = yuvs[lumPtr++];
          int Y2 = (Y1 >> 8) & 0xff;
          Y1 = Y1 & 0xff;
          int Cr = yuvs[chrPtr++];
          int Cb = ((Cr >> 8) & 0xff) - 128;
          Cr = (Cr & 0xff) - 128;

          int R, G, B;
          //generate first RGB components
          B = Y1 + ((454 * Cb) >> 8);
          if (B < 0) B = 0; if (B > 255) B = 255;
          G = Y1 - ((88 * Cb + 183 * Cr) >> 8);
          if (G < 0) G = 0; if (G > 255) G = 255;
          R = Y1 + ((359 * Cr) >> 8);
          if (R < 0) R = 0; if (R > 255) R = 255;
          int val = ((R & 0xf8) << 8) | ((G & 0xfc) << 3) | (B >> 3);

          //generate second RGB components
          B = Y1 + ((454 * Cb) >> 8);
          if (B < 0) B = 0; if (B > 255) B = 255;
          G = Y1 - ((88 * Cb + 183 * Cr) >> 8);
          if (G < 0) G = 0; if (G > 255) G = 255;
          R = Y1 + ((359 * Cr) >> 8);
          if (R < 0) R = 0; if (R > 255) R = 255;
          rgbs[yPosOut+x] = val | ((((R & 0xf8) << 8) | ((G & 0xfc) << 3) | (B >> 3)) << 16);
        }
        //skip back to the start of the chromiance values when necessary
        chrPtr = lumEnd + ((lumPtr  >> 1) / half_widthIn) * half_widthIn;
        lineEnd += half_widthIn;
      }


    (*env)->ReleaseByteArrayElements(env, imageIn, cImageIn, JNI_ABORT);
}

Я вызываю функцию в функции onPreviewFrame:

public native void yuvrgb(byte[] yuvImageIn, int widthIn, int heightIn, Bitmap imageOut, int widthOut, int heightOut);

    public void onPreviewFrame(byte[] data, Camera camera) 
    {
      yuvrgb(data,480,640,bitmapWip,480,640);
      cameraImageView.setImageBitmap(bitmapWip);
    }

Как выКак видите, я в настоящее время объявляю imageOut как растровое изображение, и я думаю, что я ошибаюсь, когда только что угадал тип.

Я не получаю никаких ошибок, приложение просто мгновенно падает.Кто-нибудь знает, что я делаю не так?

1 Ответ

1 голос
/ 05 декабря 2011

cImageOut - это массив байтов.Он объявлен в верхней части вашей функции C:

jbyte *cImageOut = (jbyte*)(*env)->GetDirectBufferAddress(env, imageOut);

Вы должны объявить его как массив байтов в своем коде Java, а затем преобразовать его в битовую карту, используя BitmapFactory.decodeByteArray

http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeByteArray%28byte[],%20int,%20int%29

...