2016-04-03 57 views
1

我需要從Facebook,Instagram或設備本身裁剪圖像。在用戶流程結束時(他選擇它們),所有的圖像都應該發送到服務器。但都在相同的寬高比(例如3/2),因此我需要手動裁剪圖像。加載和裁剪位圖無內存異常

這裏發生了什麼事在我的上傳服務和種植的一個簡單的例子:

Bitmap bitmap = ImageLoading.getLoader(UploadService.this).loadImageSync(path); 
//crop calculations 
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, w, y); 
String croppedPath = saveCroppedImage(croppedBitmap); 

我讀,然後從文件系統文件並將其編碼爲Base64將它發送到後端。

當我必須爲多個圖像執行此操作時,我經常會遇到OOM異常。也許我會以錯誤的方式去做。在服務器端裁剪是我想要做的最後一件事,因爲後端將不得不查詢Facebook或Instagram。

加載縮放版本的位圖不是一個選項,我沒有在設備上顯示它。

我曾嘗試:

  • System.gc()的
  • Bitmap.recycle();
  • 我應該在清單中使用largeHeap嗎?

注:我使用的是通用的圖像加載器的用戶流量爲好,這就是爲什麼我在上傳服務中使用它。

+1

GC不是你的問題。 Android堆分散;沒有足夠大的空閒塊來滿足分配請求。嘗試重用'Bitmap'對象(請參閱'BitmapFactory.Options'中的'inBitmap'),這可能需要您自己進行圖像加載而不是使用UIL。理想情況下,你會找到一種方法來裁剪,不涉及創建圖像的另一個副本(如'createBitmap()'可能)。在'saveCroppedImage()'中也可以做些事情來幫助你。 – CommonsWare

+0

謝謝您的評論! saveCroppedImage()只是使用FileOutputStream並將其壓縮到PNG 100.我真的無法承受質量損失。我看了一下inBitmap,但這似乎限制了不同圖像大小的使用。 –

+1

「我看了一下inBitmap,但似乎限制了不同圖像大小的使用」 - API Level 19+提供了更大的靈活性,但是,這是有限的。另一方面,除非您想開始使用NDK並在C/C++中進行圖像裁剪,否則您可能沒有多少選項。 – CommonsWare

回答

0

我想你應該在AndroidManifest文件中添加largeHeap = true。其次,如果您使用的是Universal ImageLoader,則可以下載更小尺寸的位圖。請看看下面的代碼:

ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size 
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options); // This bitmap will be of specified size. 

您還可以通過下面的鏈接瞭解Universal Image Loader

+0

加載較小版本的位圖在這裏不是一個選項,我很害怕。我們需要他們的品質。我想我可能不得不使用largeHeap,但它聽起來像一個髒碼。 –