2012-05-11 37 views
0

我調整一個Bitmapfile使用的OpenCV(Android的JNI)並保存了位圖到名爲/mnt/sdcard/org.jpg文件爲什麼我將位圖(BitmapFactory.decodeFile的輸出)保存到一個文件比原始圖像文件大?

然後用

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

得到位圖和重新這resultBitmap保存到文件/mnt/sdcard/result.jpg

那麼org.jpg大小爲100K和result.jpg大小約爲300K

爲什麼呢?在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(); 
    } 
} 
+3

嘗試在'bmp.compress(Bitmap.CompressFormat.JPEG,100,fOut);'從'100'到更低的值處撥下''quality'參數。 100 =最高質量不會給你小的JPEG圖像。 – Jens

回答

0

我不知道的OpenCV /安卓-JNI,所以我可以試着給你一個提示。

我想功能saveBitmapToFile做它在錫上說的:保存一個位圖(如在BMP file format),因爲它是。你需要首先壓縮你的bmp,也許this可能會指向你正確的方向。至於爲什麼新文件更大:如果你真的想知道(並且不僅僅是對如何解決它感興趣),請啓動一個你選擇的十六進制編輯器,並看看file header。位圖使用各種位深和壓縮,這些過程中可能會發生變化。

+0

你可以保存一個ARGB_8888位圖,這是默認的,至少我推薦(檢查Bitmap.Config)。如果您的原始bmp是RGB_565,則它是一半尺寸,因爲ARGB_8888 = 32位,RGB_565 = 16位。 – sschrass

相關問題