91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android Bitmap壓縮策略

發布時間:2020-03-03 17:27:18 來源:網絡 閱讀:200 作者:Android丶VG 欄目:移動開發
一、為什么Bitmap需要高效加載?

現在的高清大圖,動輒就要好幾M,而Android對單個應用所施加的內存限制,只有
小幾十M,如16M,這導致加載Bitmap的時候很容易出現內存溢出。如下異常信
息,便是在開發中經常需要的:

java.lang.OutofMemoryError:bitmap size exceeds VM budget

為了解決這個問題,就出現了Bitmap的高效加載策略。其實核心思想很簡單。假設
通過ImageView來顯示圖片,很多時候ImageView并沒有原始圖片的尺寸那么大,
這個時候把整個圖片加載進來后再設置給ImageView,顯然是沒有必要的,因為
ImageView根本沒辦法顯示原始圖片。這時候就可以按一定的采樣率來將圖片縮小
后再加載進來,這樣圖片既能在ImageView顯示出來,又能降低內存占用從而在一
定程度上避免OOM,提高了Bitmap加載時的性能

二、Bitmap高效加載的具體方式
1.加載Bitmap的方式

Bitmap在Android中指的是一張圖片。通過BitmapFactory類提供的四類方法:
decodeFile,decodeResource,decodeStreamdecodeByteArray,分別從文件系統,
資源,輸入流和字節數組中加載出一個Bitmap對象,其中
decodeFile,decodeResource又間接調用了decodeStream方法,這四類方法最終是
在Android的底層實現的,對應著BitmapFactory類的幾個native方法。

2.BitmapFactory.Options的參數

inSampleSize參數
上述四類方法都支持BitmapFactory.Options參數,而Bitmap的按一定采樣率進行縮
放就是通過BitmapFactory.Options參數實現的,主要用到了inSampleSize參數,即
采樣率。通過對inSampleSize的設置,對圖片的像素的高和寬進行縮放。

inSampleSize=1,即采樣后的圖片大小為圖片的原始大小。小于1,也按照1來計
算。 當inSampleSize>1,即采樣后的圖片將會縮小,縮放比例為1/(inSampleSize
的二次方)。

例如: 一張1024 ×1024像素的圖片,采用ARGB8888格式存儲,那么內存大小
1024×1024×4=4M。如果inSampleSize=2,那么采樣后的圖片內存大小:
512×512×4=1M。

注意: 官方文檔支出,inSampleSize的取值應該總是2的指數,如1,2,4,8等。
如果外界傳入的inSampleSize的值不為2的指數,那么系統會向下取整并選擇一個
最接近2的指數來代替。比如3,系統會選擇2來代替。當時經驗證明并非在所有
Android版本上都成立。

關于inSampleSize取值的注意事項: 通常是根據圖片寬高實際的大小/需要的寬高
大小,分別計算出寬和高的縮放比。但應該取其中最小的縮放比,避免縮放圖片太
小,到達指定控件中不能鋪滿,需要拉伸從而導致模糊。

例如: ImageView的大小是100×100像素,而圖片的原始大小為200×300,那么寬
的縮放比是2,高的縮放比是3。如果最終inSampleSize=2,那么縮放后的圖片大小
100×150,仍然合適ImageView。如果inSampleSize=3,那么縮放后的圖片大小小
ImageView所期望的大小,這樣圖片就會被拉伸而導致模糊。

inJustDecodeBounds參數
我們需要獲取加載的圖片的寬高信息,然后交給inSampleSize參數選擇縮放比縮
放。那么如何能先不加載圖片卻能獲得圖片的寬高信息,通過
inJustDecodeBounds=true,然后加載圖片就可以實現只解析圖片的寬高信息,并
不會真正的加載圖片,所以這個操作是輕量級的。當獲取了寬高信息,計算出縮放
比后,然后在將inJustDecodeBounds=false,再重新加載圖片,就可以加載縮放后
的圖片。

注意: BitmapFactory獲取的圖片寬高信息和圖片的位置以及程序運行的設備有
關,比如同一張圖片放在不同的drawable目錄下或者程序運行在不同屏幕密度的設
備上,都可能導致BitmapFactory獲取到不同的結果,和Android的資源加載機制
有關

3.高效加載Bitmap的流程

①將BitmapFactory.OptionsinJustDecodeBounds參數設為true并加載圖片。
②從BitmapFactory.Options中取出圖片的原始寬高信息,它們對應于outWidth
outHeight參數。

③根據采樣率的規則并結合目標View的所需大小計算出采樣率inSampleSize
④將BitmapFactory.OptionsinJustDecodeBounds參數設為false,然后重新加載
圖片。

三、Bitmap高效加載的代碼實現
  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight){
     BitmapFactory.Options options = new BitmapFactory.Options();
     options.inJustDecodeBounds = true;
     //加載圖片
     BitmapFactory.decodeResource(res,resId,options);
     //計算縮放比
     options.inSampleSize = calculateInSampleSize(options,reqHeight,reqWidth);
     //重新加載圖片
     options.inJustDecodeBounds =false;
     return BitmapFactory.decodeResource(res,resId,options);
  }

  private static int calculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) {
     int height = options.outHeight;
     int width = options.outWidth;
     int inSampleSize = 1;
     if(height>reqHeight||width>reqWidth){
         int halfHeight = height/2;
         int halfWidth = width/2;
         //計算縮放比,是2的指數
         while((halfHeight/inSampleSize)>=reqHeight&&(halfWidth/inSampleSize)>=reqWidth){
               inSampleSize*=2;
         }
     }

     return inSampleSize;
  }

這個時候就可以通過如下方式高效加載圖片:

  mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(),R.mipmap.ic_launcher,100,100);

除了BitmapFactorydecodeResource方法,其他方法也可以類似實現。

更多內容詳情請關注我的GitHub:https://github.com/xiangjiana/Android-MS

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

离岛区| 新邵县| 舞钢市| 吉隆县| 东丰县| 旅游| 双城市| 镇平县| 密云县| 佛山市| 赤峰市| 常宁市| 温宿县| 广德县| 天柱县| 东乡| 兴安县| 波密县| 蕲春县| 盈江县| 甘泉县| 涞水县| 长子县| 古丈县| 咸宁市| 泰安市| 綦江县| 潜江市| 海安县| 高淳县| 北辰区| 安泽县| 陇川县| 吉水县| 英吉沙县| 南木林县| 松潘县| 全椒县| 大石桥市| 昌都县| 砀山县|