为什么我将位图(BitmapFactory.decodeFile的输出)保存到文件中比原始图像文件大?

时间:2012-05-11 06:02:37

标签: android opencv bitmap filesize bitmapfactory

我使用opencv(android-jni)调整位图文件的大小,并将out位图保存到名为/mnt/sdcard/org.jpg的文件中

然后使用

resultBitmap = BitmapFactory.decodeFile("/mnt/sdcard/org.jpg"); 

获取位图并将此resultBitmap重新保存到文件/mnt/sdcard/result.jpg

然后org.jpg大小为100k,result.jpg大小约为300k

为什么?

我的resize方法在jni中使用opencv,如下所示:

int FUN_ENTRY JNICALL Java_com_funlib_imagefilter_ImageUtily_nativeResizeBitmap(    
                                                                                JNIEnv* env, jobject obj , jstring srcPath , jstring destPath,  int w , int h , int quality)
{
    char* srcPath1 = jstringTostring(env , srcPath);
    IplImage *src = cvLoadImage(srcPath1,CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
    if(srcPath1!=NULL)
    {
        free(srcPath1);
        srcPath1 = NULL;
    }
    if(src==NULL)
    {
        return -1;
    }

    CvSize sz;
    double rate1 = ((double) src->width) / (double) w + 0.1; 
    double rate2 = ((double) src->height) / (double) h + 0.1; 

    double rate = rate1 > rate2 ? rate1 : rate2; 
    sz.width = (int) (((double) src->width) / rate); 
    sz.height = (int) (((double) src->height) / rate); 
    IplImage *desc = cvCreateImage(sz,src->depth,src->nChannels);
    if(desc==NULL)
    {
        cvReleaseImage(&src);
        return -1;
    }
    cvResize(src,desc,CV_INTER_CUBIC);
    if(desc==NULL)
    {
        cvReleaseImage(&src);
        return -1;
    }
    char* destPath1 = jstringTostring(env , destPath);

    int p[3];
    p[0] = CV_IMWRITE_JPEG_QUALITY;
    p[1] = quality;
    p[2] = 0;

    cvSaveImage(destPath1 , desc , p);
    cvReleaseImage(&src);
    cvReleaseImage(&desc);
    if(destPath1!=NULL)
    {
        free(destPath1);
        destPath1 = NULL;
    }

    return 0;
}

我的主要是

File f = new File(filePath);
    String tmpDestPath = f.getParent();
    if(!tmpDestPath.endsWith(File.separator))
        tmpDestPath += File.separator;
    tmpDestPath += "org.jpg";
    int ret = nativeResizeBitmap(filePath, tmpDestPath, width, height , quality);         //get the org.jpg file
    Bitmap bmp = null;
    if(ret == 0){
        bmp = BitmapFactory.decodeFile(tmpDestPath);
    }

    try {
        ImageUtily.saveBitmapToFile("result", bmp);  //get the result.jpg file
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

我的saveBitmapToFile是

    public static void saveBitmapToFile(String fileName, Bitmap bmp) throws IOException
{
    File f = new File("/sdcard/DCIM/TEMP/" + fileName + ".jpg");
    f.createNewFile();
    FileOutputStream fOut = null;
    try {
        fOut = new FileOutputStream(f);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
    try {
        fOut.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        fOut.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:0)

我不了解OpenCV / Android-JNI,所以我可以试着给你一个提示。

我认为函数saveBitmapToFile执行它在锡上所说的内容:保存位图(如BMP file format中所示)。您需要首先压缩bmp,也许this可能会指向正确的方向。

至于为什么新文件更大:如果你真的想知道(并且不仅仅对如何修复它感兴趣),请启动你选择的Hex编辑器并查看file header 。位图使用可能在此过程中更改的各种位深度和压缩。