2013-12-09 40 views
1

我仍然包裹我的頭周圍的位圖在Android上如何工作的。我目前的情況是 - 我試圖顯示圖像的網格視圖,但是我在8張左右的圖片中發現了內存不足的錯誤。收縮的Android位圖而不保存爲JPEG文件,以避免內存不足的錯誤

我做到這一點現在我使用的自定義相機的方式(延伸surfaceview和實施surfaceholder.callback)拍攝照片,從使用YUV420SP轉換函數的onPreviewFrame方法字節數組解碼成一個int []數組和然後從該數組創建一個位圖。我這樣做的原因有兩個,1.將數據流保存到sqlite數據庫中的blob中,稍後再傳輸到服務器; 2.避免將它保存爲手機中可以改變的jepg用。

如果有更好的方法來做到這一點我願意聽到這種事情,但現在我正在尋找一個答案是會幫我往下縮圖像尺寸,當我顯示它從調用它後數據庫或將其保存到數據庫之前。我已經看過關於這個主題的其他主題,但是目前爲止我看到的所有內容都需要將其保存爲jpeg,然後使用bitmapfactory.options將文件位置解碼爲位圖。有沒有人知道直接使用字節數組參數的選項,甚至使用YUV420SP轉換之後的方式?

讓我知道是否需要任何更多的澄清。

回答

0

所以,問題是你沒有顯示它們到GridView控件之前縮小圖像,所以當你創建位圖那些INT [],您應該顯示它們之前創建一個按比例縮小的位圖的版本。

會有這樣的事情:

public static byte[] intArraysToByteArrays(int[] data){ 
    ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);   
    IntBuffer intBuffer = byteBuffer.asIntBuffer(); 
    intBuffer.put(data); 

    return byteBuffer.array(); 
} 

public static Bitmap decodeSampleBitmapFromByteStream(byte[] data , int reqWidth, int reqHeight){ 
    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeByteArray(data, 0, data.length, options); 

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

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 

    return BitmapFactory.decodeByteArray(data, 0, data.length, options); 
} 


/** 
* Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding 
* bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates 
* the closest inSampleSize that will result in the final decoded bitmap having a width and 
* height equal to or larger than the requested width and height. This implementation does not 
* ensure a power of 2 is returned for inSampleSize which can be faster when decoding but 
* results in a larger bitmap which isn't as useful for caching purposes. 
* 
* @param options An options object with out* params already populated (run through a decode* 
*   method with inJustDecodeBounds==true 
* @param reqWidth The requested width of the resulting bitmap 
* @param reqHeight The requested height of the resulting bitmap 
* @return The value to be used for inSampleSize 
*/ 
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; 

     // This offers some additional logic in case the image has a strange 
     // aspect ratio. For example, a panorama may have a much larger 
     // width than height. In these cases the total pixels might still 
     // end up being too large to fit comfortably in memory, so we should 
     // be more aggressive with sample down the image (=larger inSampleSize). 

     final float totalPixels = width * height; 

     // Anything more than 2x the requested pixels we'll sample down further 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 

     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 
    } 
    return inSampleSize; 
} 

注:我沒有測試過的代碼,但我非常有信心它應該工作的罰款。爲了獲得更好的性能,所有這些應該在後臺線程中運行。

+0

我已經嘗試使用此和示例本教程https://developer.android.com/training/displaying-bitmaps/load-bitmap.html但它返回一個空的圖像。 – zafrani

相關問題