【问题标题】:Display IplImage as Android Bitmap将 IplImage 显示为 Android 位图
【发布时间】:2012-03-22 08:51:13
【问题描述】:

我正在开发一个使用 OpenCV 的面部检测 Android 应用程序 2.3.1 库。我找到了一些代码,可以让我在上面拍照 我的三星 GT-P1000 并将其保存在图库中。然后我想选择 画廊中的图像允许 .cpp 文件使用 OpenCV 职能。这需要位图到 IplImage 的转换(.java 和.cpp代码sn-ps在下面添加)。

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;
}

但是我需要另一个 JNIEXPORT 函数来转换 IplImage 到位图数据。因此将使用最后 4 行代码。应填充 imageData,以便 BitmapFactory 可以对其进行解码。我遇到了大量示例,这些代码 sn-ps 也来自这些示例。但是我无法为我的问题找到解决方案。有人有什么建议吗?

【问题讨论】:

    标签: android opencv bitmap java-native-interface


    【解决方案1】:

    您似乎打算使用压缩格式,这是可行的,但很复杂。 在这里,我给出了一个使用未压缩数据的解决方案。 因为android中的Bitmap基本都是rgba格式,所以除了字节对齐问题,可以直接使用IplImage数据创建bitmap。

    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);
    

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 2014-10-14
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多