2012-12-07 62 views
2

就這樣,我創建了一個Android應用程序,我需要顯示某些URL的圖像。不幸的是,圖像太大,當我將它傳遞給drawable而沒有任何解碼時,它會給我一個Out of Memory異常。Android:從url傳遞大圖像到ImageView

因此,我試圖先使用BitmapFactory.decodeStream解碼圖像。

下面是一些代碼:

首先,我用的圖像解碼方法:

public static Bitmap decodeSampledBitmapFromResource(Resources res, String src, 
      int reqWidth, int reqHeight) { 

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

     InputStream input = null; 
     InputStream input2 = null; 

     Rect paddingRect = new Rect(-1, -1, -1, -1); 

     try { 
      URL url = new URL(src); 
      HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
      connection.setDoInput(true); 
      connection.connect(); 
      input = connection.getInputStream(); 
      //input2 = connection.getInputStream(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return null; 
     } 

     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(input, paddingRect, options); 

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

     try { 
     input.reset(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

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

     return BitmapFactory.decodeStream(input, paddingRect, options); 
    } 

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 = 40; 

    if (height > reqHeight || width > reqWidth) { 
     if (width > height) { 
      inSampleSize = Math.round((float)height/(float)reqHeight); 
     } else { 
      inSampleSize = Math.round((float)width/(float)reqWidth); 
     } 
    } 
    return inSampleSize; 
} 

然後,我就在活動的OnCreate該方法調用:

imageFrame1.setImageBitmap(
       decodeSampledBitmapFromResource(getResources(), src, 100, 100)); 

由於代碼現在,當我在第一次解碼輸入流後嘗試重置輸入流時,它會捕獲IOException,然後我得到LogCat消息:SKImageDecoder :: Factory Returne d空。

如果我刪除input.reset();從代碼,然後我得到相同的LogCat消息,只是沒有IOException。

有點難以忍受這一點,希望有人在這裏有一些建議?

回答

1

您不能重置HTTP連接的流,因爲底層邏輯沒有緩存(足夠)的流。

創建一種方法,將圖片寫入本地存儲(光盤或內存),然後進行分析。可以選擇同時做兩件事(需要更多的努力)。

+0

我可能會誤解你,但如果我嘗試下載圖片而未解碼爲較小的圖片,則由於圖片的大小而導致出現「內存不足」異常。 – Hallow

+0

將其存儲在光盤上並從光盤解碼。並通過光盤,我正在考慮閃存(存儲卡或內部)。 – ThomasRS

0

請記住,inputStream可能不支持重置。而且,你必須首先調用mark()來標記該點,inputStream應該重置爲。要檢查是否支持標記/重置,請調用InputStream.markSupported()。

沒有標記/重置,你可以下載圖像到本地文件。它不會導致OutOfMemory,並允許您以與從Web(使用子採樣)執行相同的方式解碼FileInputStream中的圖像。