2013-04-24 79 views
2

天,我花了這個工作。也許是幾個星期。從字面上看。 :(Android中的編程圖像調整大小,內存問題

所以我有一個SD卡上的圖像,很可能是從內置相機出來的,我想拍攝該圖像並將其縮小到任意大小(但始終更小,並且不會更大)。我的代碼使用標準的Android位圖方法來解碼,調整大小,重新壓縮和保存圖像。只要最終圖像小於3MP左右,一切都可以正常工作。如果圖像較大,或者如果我嘗試做幾個這些應用程序一旦崩潰,就會發生OutOfMemoryError事件,我知道爲什麼會發生這種情況,而且我知道這是出於完全合法的原因,我只是希望它不會再發生了。在這裏啓動一個火箭,我想要做的就是調整一個攝像頭圖像並將其轉儲到一個OutputStream或甚至是一個臨時文件樂。當然有人在那裏肯定做過這樣的事情。我不需要你爲我寫代碼,也不需要我的手。但是,在我的各種編程墮胎和癡迷谷歌搜索的日子之間,我甚至不知道應該走哪個方向。粗略地說,沒有人知道如何解碼JPEG,對其進行下采樣,將其重新壓縮爲JPEG,然後發送出去在OutputStream上沒有分配大量的內存?

+0

喜歡請發表您的logcat,會幫助你 – umesh 2013-04-24 05:24:53

+0

你能告訴你想最後用此圖片做什麼,我的意思是上傳或顯示在ImageView等.. – SREEJITH 2013-04-24 05:29:24

+0

嘿adi,爲什麼你不試試@Evan Lis解決方案,這是最好的,調整和顯示圖像的視野。 – umesh 2013-04-24 05:34:22

回答

0

以下代碼來自我以前的項目。關鍵點是「options.inSampleSize」。

public static Bitmap makeBitmap(String fn, int minSideLength, int maxNumOfPixels) { 
    BitmapFactory.Options options; 
    try { 
     options = new BitmapFactory.Options(); 

     options.inPurgeable = true; 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(fn, options); 
     if (options.mCancel || options.outWidth == -1 
       || options.outHeight == -1) { 
      return null; 
     } 
     options.inSampleSize = computeSampleSize(
       options, minSideLength, maxNumOfPixels); 
     options.inJustDecodeBounds = false; 
     //Log.e(LOG_TAG, "sample size=" + options.inSampleSize); 

     options.inDither = false; 
     options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
     return BitmapFactory.decodeFile(fn, options); 
    } catch (OutOfMemoryError ex) { 
     Log.e(LOG_TAG, "Got oom exception ", ex); 
     return null; 
    } 
} 

private static int computeInitialSampleSize(BitmapFactory.Options options, 
     int minSideLength, int maxNumOfPixels) { 
    double w = options.outWidth; 
    double h = options.outHeight; 

    int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 : 
      (int) Math.ceil(Math.sqrt(w * h/maxNumOfPixels)); 
    int upperBound = (minSideLength == UNCONSTRAINED) ? 128 : 
      (int) Math.min(Math.floor(w/minSideLength), 
      Math.floor(h/minSideLength)); 

    if (upperBound < lowerBound) { 
     // return the larger one when there is no overlapping zone. 
     return lowerBound; 
    } 

    if ((maxNumOfPixels == UNCONSTRAINED) && 
      (minSideLength == UNCONSTRAINED)) { 
     return 1; 
    } else if (minSideLength == UNCONSTRAINED) { 
     return lowerBound; 
    } else { 
     return upperBound; 
    } 
} 
+0

最佳答案,它的唯一辦法 – umesh 2013-04-24 05:35:07

3

好吧我知道這有點晚了,但是,我有這個問題,我找到了解決辦法。這實際上很簡單,我相信它支持回api 10(我不知道10之前)。我用我的手機試了一下。這是一個帶有8mp照相機的三星Galaxy S2,代碼將照相機圖像完美調整爲168x168以及我在網上找到的圖像。我也使用文件管理器檢查了圖像。我從來沒有嘗試調整圖像大小resoulation。

private Bitmap resize(Bitmap bp, int witdh, int height){ 
    return Bitmap.createScaledBitmap(bp, width, height, false); 
} 

,你可以將它保存這個

private void saveBitmap(Bitmap bp) throws FileNotFoundException{ 
    String state = Environment.getExternalStorageState(); 
    File folder; 
    //if there is memory card available code choose that 
    if (Environment.MEDIA_MOUNTED.equals(state)) { 
     folder=Environment.getExternalStorageDirectory(); 
    }else{ 
     folder=Environment.getDataDirectory(); 
    } 
    folder=new File(folder, "/aaaa"); 
    if(!folder.exists()){ 
     folder.mkdir(); 
    } 

    File file=new File(folder, (int)(Math.random()*10000)+".jpg"); 
    FileOutputStream os=new FileOutputStream(file); 
    bp.compress(Bitmap.CompressFormat.JPEG, 90, os); 
} 

感謝這個link