使用Android NDK问题调用JNI

时间:2011-12-03 15:57:02

标签: android image-processing camera android-ndk

我有一个C函数,我使用Android NDK从Java调用。基本上它需要相机数据并将其从YUV转换为RGB格式。问题是我不确定在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 个答案:

答案 0 :(得分:1)

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