2013-10-30 100 views
15

我需要將圖像從文件發送到服務器。服務器請求圖像的分辨率爲2400x2400。BitmapFactory.decodeFile內存不足與圖像2400x2400

我試圖做的是:

1)使用BitmapFactory.decodeFile使用正確的inSampleSize得到一個位圖。

2)壓縮的JPEG圖像具有40%

3)質量編碼所述圖像中向服務器發送

的base64

4)我不能達到的第一步,它引發內存不足異常。我確定inSampleSize是正確的,但是即使在inSampleSize中,位圖也很大(在DDMS中大約爲30 MB)。

任何想法如何做到這一點?我可以在不創建位圖對象的情況下執行這些步驟嗎?我的意思是在文件系統而不是RAM內存上做。

這是當前的代碼:

// The following function calculate the correct inSampleSize 
Bitmap image = Util.decodeSampledBitmapFromFile(imagePath, width,height); 
// compressing the image 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
image.compress(Bitmap.CompressFormat.JPEG, 40, baos); 
// encode image 
String encodedImage = Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT)); 


public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     // Calculate ratios of height and width to requested height and width 
     final int heightRatio = Math.round((float) height/(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will guarantee 
     // a final image with both dimensions larger than or equal to the 
     // requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 

    return inSampleSize; 
} 

public static Bitmap decodeSampledBitmapFromFile(String path,int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(path, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(path,options); 
} 
+0

至u做會得到一些想法http://developer.android.com/training/displaying-bitmaps/manage-memory.html –

+0

getBitmap()。recycle(); –

+0

你有一個文件中的圖像,對吧?只需將此文件發送到服務器並在那裏進行必要的轉換。 – Henry

回答

46

你可以跳過ARGB_8888,並使用RGB_565代替,然後抖動然後圖像保持良好的質量

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = false; 
options.inPreferredConfig = Config.RGB_565; 
options.inDither = true; 
+0

它減小了位圖13 MB的大小,並且它正在工作。非常感謝! – alasarr

+0

太棒了!有用!謝謝! – Ignacio

1

你必須使用BitmapFactory.OptionsinJustDecodeBounds設置爲true。通過這種方式,您可以加載有關位圖的信息並計算下采樣的值(例如,inSampleSize

+0

我已經做到了,它不起作用。 – alasarr

+0

我想看看它。你能用代碼片段更新帖子嗎? – Blackbelt

+0

我剛更新了帖子。謝謝! – alasarr

1

不要將圖像作爲位圖加載,將其轉換爲數組,然後發送它。

代替:

它讀成一個文件,JPG格式。使用文件字節數組對其進行編碼,然後發送文件。

將其加載到位圖中,會導致不必要的巨大內存問題。以位圖格式重新表示的圖像將比需要的要多20倍或更多的內存。

在服務器端,您也需要將它視爲一個文件。而不是位圖。

這裏是一個鏈接到加載文件爲byte []:Elegant way to read file into byte[] array in Java

+0

我需要一個位圖,因爲我需要調整它的大小並對其進行壓縮。原始圖像大小爲12MB,我想發送到700KB左右的服務器,而不是原始圖像的12MB。 – alasarr

+0

@alasarr啊我的錯誤。你必須錯誤地抽樣。請參閱http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – Doomsknight

+0

@alasarr只要你知道。位圖格式的「2400x2400」圖像,每像素使用2個字節,大小爲11MB。無論jpg格式是否爲「700KB」。或者'4字節'表示是'22MB' – Doomsknight