2012-03-22 52 views
1

我正在使用OpenCV 2.3.1库的FaceDetect Android应用程序。我找到了一些代码,可以让我在 上制作我的三星GT-P1000的照片并将其保存在图库中。然后我想从图库中选择 ,它允许.cpp文件使用OpenCV 函数。这需要一个位图到IplImage的转换(下面添加.java 和.cpp代码片段)。将IplImage显示为Android位图

Java代码看起来是这样的:

Bitmap bitmap = BitmapFactory.decodeFile(mCurrentImagePath); 
Log.i(TAG, mCurrentImagePath); 
int width = bitmap.getWidth(); 
int height = bitmap.getHeight(); 
int[] pixels = new int[width * height]; 
bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 
opencv.setSourceImage(pixels, width, height); 
byte[] imageData = opencv.getSourceImage(); 
bitmap = BitmapFactory.decodeByteArray(imageData, 0, 
imageData.length); 
mImageView.setImageBitmap(bitmap); 

的C++代码看起来是这样的:

IplImage * pImage = NULL; 
IplImage * loadpixels(int * pixels, int width, int height); 
IplImage * getIplImageFromIntArray 
    (JNIEnv* env, jintArray array_data, jint width, jint height); 

JNIEXPORT jboolean JNICALL Java_org_opencv_example_pruts_Test1OpenCV_setSourceImage 
    (JNIEnv * env, jobject thiz, jintArray photo_data, jint width, jint height) 
{ 
    if(pImage != NULL) 
    { 
     cvReleaseImage(&pImage); 
     pImage = NULL; 
    } 

    pImage = getIplImageFromIntArray(env, photo_data, width, height); 
    if(pImage == 0) 
    { 
     return 0; 
    } 

    return 1; 
} 

但是我需要其中的IplImage 转换为位图数据的另一个JNIEXPORT功能。因此最后4行代码将被使用。应该填充imageData以便BitmapFactory可以解码它。我遇到了很多示例,这些代码片段也来自这些代码片段。然而,我无法找到解决我的问题的方法。有没有人有一些建议?

回答

4

看来你打算使用压缩格式,它是可行的,但很复杂。 这里我给出一个使用未压缩数据的解决方案。 由于android中的位图基本上是rgba格式,所以您可以直接使用IplImage数据创建位图,除了字节对齐问题。

JNIEXPORT jintArray JNICALL Java_org_opencv_example_pruts_Test1OpenCV_getSourceImage 
    (JNIEnv * env, jobject thiz){  
    if(pImage == 0) 
    { 
     return NULL; 
    } 

    int len = pImage->width * pImage->height * 4; 
    jintArray rgbaData = env->NewIntArray(len); 
    if(pImage->nChannels == 4){ 
     env->SetIntArrayRegion(rgbaData,0,len,(jint*)pImage->imageData); 
    }else if(pImage->nChannels == 3){ 
     IplImage* t = cvCreateImage(cvGetSize(pImage),8,4); 
     for(int h = 0; h< pImage->height; h++){ 
      char* pt= t->imageData + h * t->widthStep; 
      char* pImg = pImage->imageData+ h * pImage->widthStep; 
      for(int w =0 ; w < pImage->width; w++){ 
       memcpy(pt,pImg,3); 
       pt[3] = 255;//alpha 
       pt+=4; 
       pImg += 3; 
      } 
     } 
     env->SetIntArrayRegion(rgbaData,0,len,(jint*)t->imageData); 
     cvReleaseImage(&t); 
    }else { 
     // if pImage -> nChannels == 1 , handle it in the way you prefer 
     // I donot think your image is gray ,so forget about this situation 
    } 

    cvReleaseImage(&pImage); 
    return rgbaData; 
} 

和Java代码应该是这样的:

int[] imageData = opencv.getSourceImage(); 
bitmap = Bitmap.createBitmap(imageData, 0, width,width, height, Config.ARGB_8888); 
+0

代码没有测试 – zhijie 2012-03-22 10:13:33