今天給你們分享一些圖片處理經常使用技術方案,Android應用開發的朋友必需要了解呀! java
衆所周知在Android應用開發中在對圖片處理時,稍有不慎就會出現如下異常: 性能
java.lang.OutofMemoryError: bitmap size exceeds VM budget. 優化
如下幾點是加載Bitmap時須要謹慎對待的緣由: code
一般移動設備的系統資源有限,Android設備會給每一個應用分配16M的內存空間。 Android的兼容性定義文件(CDD)中第3.7節。提供了虛擬機的兼容性所需的各類屏幕尺寸和密度及最低的應用程序的內存。優化應用程序應參考這個最小的內存限制。然而,許多廠商的Android設備的系統會較高的限制配置。 對象
Bitmap會佔用大量的內存,尤爲是帶有豐富的圖像的應用,像照片管理等應用。例如, 在Galaxy Nexus相機拍照的最高的爲2592x1936像素(5百萬像素)。若是使用bitmap 配置是ARGB_8888(默認從Android2.3起),那麼這個圖片加載到內存須要大約19MB的內存(2592*1936*4個字節),在某些設備上會當即耗盡應用程序的內存致使異常發生。 圖片
Android應用程序UI的常常須要一次加載多個圖片。如在ListView,GridView和ViewPager中,一般在一屏中包括在多張圖片。 內存
如何高效的加載圖片 資源
圖片尺寸與大小各類各樣。多數狀況下大於用戶要在應用中使用的圖片大小。例如:系統的Gallery應用中管理相機拍的照片時 , 照片的尺寸像素每每大於屏幕的密度。 開發
基於內存限制的緣由,理想狀況下你須要加載低分辨率的圖片到內存中。低分辨率的圖片與UI控件的大小保持一致便可,高分辨率的圖片對用戶來講並不明顯,然而對圖片進行縮放操做也會佔用寶貴的內存和額外的性能開銷。 圖片處理
今天給你們分享一下如何不佔用內存空間狀況下對圖片進行縮放採樣。
讀取Bitmap 的尺寸與類型
BitmapFactory類提升多種方法(decodeByteArray(), decodeFile(), decodeResource(), 等等)用來從不一樣資源文件中加載圖片。根據圖片資源類型選擇相應的方法進行加載,這些方法在構造Bitmap對象時會費配內存,所以很容易致使OutOfMemory異常,你能夠經過 BitmapFactory.Options類爲不一樣解碼方式參數;設置inJustDecodeBounds 爲true是能夠避免內存分配,結果爲Null,可是附帶了outWidth, outHeight and outMimeType.信息。經過這種方式你就能夠在構在Bitmap對象前獲取它的尺寸/類型信息
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType;
在使用圖片前必定要檢查圖片的尺寸以免內存溢出,除非你卻定使用的圖片尺寸合適且不會耗費過多的內存。
如何加載縮放的圖片到內存中
如今你已經知道如何獲取圖片的大小了,這樣在使用圖片時你就能夠決定是加載原圖仍是加載縮放的圖片了,如下幾點須要注意:
估算一下原圖的內存使用狀況
你的應用中容許分配給圖片的內存大小
使用圖片的ImageView或其餘UI組件大小。
使用設備的屏幕大小與密度
例如:1024*768的圖片實際上只須要在ImageView中顯示128*96的縮略圖
在BitmapFactory.Options 中設置inSampleSize爲合適的採樣率,以獲取合適尺寸的圖片。
例如:2048*1536的圖片將 inSampleSize 位置爲 4時能夠獲得512*384的圖片,若是加載的內存中爲0.75M,遠低於原圖的12M內存空間(Bitmap設置爲ARGB_8888時),下面是一個基於須要的圖片大小獲取合適採樣率例子:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
經過上面的方法能夠很容易的把一個大圖片以100*100的縮略圖的大小設置到ImageView中,例子以下:
mImageView.setImageBitmap( decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
你能夠參考上面的方式選擇你須要的加載方式加載圖片。