Android Bitmap壓縮方式分析
Android Bitmap壓縮方式分析
在網(wǎng)上調(diào)查了圖片壓縮的方法并實(shí)裝后,大致上可以認(rèn)為有兩類(lèi)壓縮:質(zhì)量壓縮(不改變圖片的尺寸)和尺寸壓縮(相當(dāng)于是像素上的壓縮);質(zhì)量壓縮一般可用于上傳大圖前的處理,這樣就可以節(jié)省一定的流量,畢竟現(xiàn)在的手機(jī)拍照都能達(dá)到3M左右了,尺寸壓縮一般可用于生成縮略圖。
在Android開(kāi)發(fā)中我們都會(huì)遇到在一個(gè)100*100的ImageView上顯示一張過(guò)大的圖片,如果直接把這張圖片顯示上去對(duì)我們應(yīng)用沒(méi)有一點(diǎn)好處反而存在OOM的危險(xiǎn),所以我們有必要采用一種有效壓縮方式來(lái)顯示上去。
private void calculateBitmapInSimpleSize() {
Bitmap _bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_homepage);
getBitmapDatas(_bitmap);
BitmapFactory.Options optioins = new BitmapFactory.Options();
optioins.inJustDecodeBounds = true;
// optioins.inPreferredConfig = Bitmap.Config.RGB_565;//11158560
optioins.inPreferredConfig = Bitmap.Config.ARGB_8888;//22317120
BitmapFactory.decodeResource(getResources(), R.drawable.bg_homepage, optioins);
int reqWidth = optioins.outWidth;
int reqHeight = optioins.outHeight;
Log.w(TAG, "reqWidth = " + reqWidth);
Log.w(TAG, "reqHeight = " + reqHeight);
int inSampleSize = 1;
final int widthRatio = Math.round((float)reqWidth / 100f);
final int heigthRatio = Math.round((float) reqHeight / 100f);
// 取最小值 這將保證壓縮出來(lái)的圖片大于或者等于請(qǐng)求的寬度或者高度
inSampleSize = widthRatio > heigthRatio ? heigthRatio : widthRatio;
Log.w(TAG, "first inSampleSize = " + inSampleSize);
final int totalPixel = 100 * 100;
final int totalReqPixel = reqWidth * reqHeight * 2;
Log.w(TAG, "totalReqPixel = " + totalReqPixel);
while (totalPixel / (inSampleSize * inSampleSize) > totalReqPixel) {
Log.w(TAG, "totalPixel = " + (totalPixel / (inSampleSize * inSampleSize)));
inSampleSize ++;
}
Log.w(TAG, "LastInSampleSize = " + inSampleSize);
optioins.inJustDecodeBounds = false;
Bitmap lastBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_homepage, optioins);
getBitmapDatas(lastBitmap);
mImageView.setImageBitmap(lastBitmap);
}
通過(guò)打印log我們可以清楚發(fā)現(xiàn)一張?jiān)嫉膱D片占有22317120字節(jié),經(jīng)過(guò)壓縮后11158560(RGB_565)/ 22317120(RGB8888)明顯所占用的內(nèi)存都減少了,盡量降低這種情況帶來(lái)的OOM。
做法:
1.optioins.inJustDecodeBounds = true設(shè)置為true可用于讀取該bitmap的寬高且不會(huì)占用內(nèi)存。
2.optioins.inPreferredConfig = Bitmap.Config.RGB_565設(shè)置在內(nèi)存中以占用最少的方式,相比RGB_8888只有其一半的內(nèi)存占有。
3.final int widthRatio = Math.round((float)reqWidth / 100f);
final int heigthRatio = Math.round((float) reqHeight / 100f);
inSampleSize = widthRatio > heigthRatio ? heigthRatio : widthRatio;
計(jì)算壓縮比例,取最小值 這將保證壓縮出來(lái)的圖片大于或者等于請(qǐng)求的寬度或者高度。
4.在要顯示到ImageView的時(shí)候optioins.inJustDecodeBounds = false設(shè)回false這樣就能正常顯示了
// 計(jì)算bitmap所占內(nèi)存值
public void getBitmapDatas(Bitmap bitmap) {
Log.w(TAG, "Bitmap size = " + bitmap.getByteCount());
}
采用以上的壓縮方式 我們就能避免一張過(guò)大的圖片”浪費(fèi)”的顯示在ImageView上造成內(nèi)存消耗過(guò)大。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
android開(kāi)發(fā)教程之ubuntu使用adb連接小米2的步驟和adb調(diào)試方法
這篇文章主要介紹了ubuntu中使用adb連接小米2的步驟和adb調(diào)試方法,需要的朋友可以參考下2014-02-02
android getActivity.findViewById獲取ListView 返回NULL的方法
下面小編就為大家?guī)?lái)一篇android getActivity.findViewById獲取ListView 返回NULL的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
Android中通過(guò)RxJava進(jìn)行響應(yīng)式程序設(shè)計(jì)的入門(mén)指南
響應(yīng)式編程在Android中的運(yùn)用是非常犀利的,比如在異常處理和調(diào)度器方面,這里我們將從生命周期等方面來(lái)講解Android中通過(guò)RxJava進(jìn)行響應(yīng)式程序設(shè)計(jì)的入門(mén)指南:2016-06-06
Android實(shí)戰(zhàn)打飛機(jī)游戲之無(wú)限循環(huán)的背景圖(2)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)戰(zhàn)打飛機(jī)游戲之無(wú)限循環(huán)的背景圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
Android5.0 旋轉(zhuǎn)菜單實(shí)例詳解
這篇文章主要介紹了 Android5.0 旋轉(zhuǎn)菜單的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2016-12-12
Android一個(gè)類(lèi)實(shí)現(xiàn)錄音與播放實(shí)例
大家好,本篇文章主要講的是Android一個(gè)類(lèi)實(shí)現(xiàn)錄音與播放實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02
Android手勢(shì)密碼view學(xué)習(xí)筆記(二)
這篇文章主要為大家詳細(xì)介紹了Android手勢(shì)密碼view的第二篇學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android 實(shí)現(xiàn)釘釘自動(dòng)打卡功能
這篇文章主要介紹了Android 實(shí)現(xiàn)釘釘自動(dòng)打卡功能的步驟,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03

