2016-05-23 138 views
0

是否有任何庫或任何有效的方式來處理位圖。位圖內存泄漏大圖像

我需要發送1-10圖像到服務器。圖像從3到15兆字節。 我們以base64格式發送字符串。但是這個過程需要太多的內存和應用程序爆炸。我試圖優化應用程序並釋放內存,但是在大多數情況下仍然有內存異常,我也使用大堆。

protected Void doInBackground(Void... voids) { 

      for (int i = 0; i < mUriList.size(); i++) { 
       Log.e("encodeImage bitmap", Integer.toString(i) + " " + mUriList.get(i)); 
       mBitmap = getBitmapFromUri(mUriList.get(i)); 
       String imageNamePath = mImageNameList.get(i); 

       // FIXME: 5/23/16 OOM kod 10 slika 

       ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
       mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); 

       byte[] array = stream.toByteArray(); 
       encoded_string = Base64.encodeToString(array, Base64.DEFAULT); 

       array = null; 
       //encoded_image_list.add(encoded_string); 
       makeRequest(encoded_string, imageNamePath, i); 
       mBitmap.recycle(); 
       mBitmap = null; 
       try { 
        stream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       stream = null; 
       encoded_string = null; 
       System.gc(); 
      } 
      return null; 
     }.... 

獲取圖像從位圖

public Bitmap getBitmapFromUri(Uri uri) { 
     Bitmap bitmap = null; 
     try { 
      bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return bitmap; 
    } 

PS:我不能降低圖像質量!

+0

基本上,你想base64它以後發送它? –

+0

我把它轉換成base64並且用齊射發送。它工作正常,但有時我得到內存泄漏異常應用程序需要從150到650內存轉換過程中。我在makeRequest函數中發送圖像。我將圖像1轉換爲1,並在異步任務中將它們逐一發送... – Adnan

+0

可以在base64之前縮小圖像大小嗎? –

回答

0

因此,假設您有能力重新編寫服務器端的請求,以通過多部分POST請求處理圖像上載。 (因爲你寫的後端API也證實!)

我把代碼的樣片與OkHttp客戶在這裏:

public final class PostMultipart { 
    /** 
    * The imgur client ID for OkHttp recipes. If you're using imgur for anything other than running 
    * these examples, please request your own client ID! https://api.imgur.com/oauth2 
    */ 
    private static final String IMGUR_CLIENT_ID = "9199fdef135c122"; 
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); 

    private final OkHttpClient client = new OkHttpClient(); 

    public void run() throws Exception { 
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image 
    RequestBody requestBody = new MultipartBody.Builder() 
     .setType(MultipartBody.FORM) 
     .addFormDataPart("title", "Square Logo") 
     .addFormDataPart("image", "logo-square.png", 
      RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) 
     .build(); 

    Request request = new Request.Builder() 
     .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) 
     .url("https://api.imgur.com/3/image") 
     .post(requestBody) 
     .build(); 

    try (Response response = client.newCall(request).execute()) { 
     if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

     System.out.println(response.body().string()); 
    } 
    } 

    public static void main(String... args) throws Exception { 
    new PostMultipart().run(); 
    } 
} 

全樣本這裏Github上OkHttp食譜:https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java

據我所知, OkHttp客戶端會讀取並上傳圖像文件,使其分辨率更小。這將避免在讀取base64字符串時必須將圖像作爲大塊內存處理的情況。