圖片像素
Android中圖片有四種屬性姓蜂,分別是:
ALPHA_8:每個像素占用1byte內(nèi)存
ARGB_4444:每個像素占用2byte內(nèi)存
ARGB_8888:每個像素占用4byte內(nèi)存 (默認(rèn))
RGB_565:每個像素占用2byte內(nèi)存
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565; // 圖像以RGB_565讀取
Android默認(rèn)的顏色模式為ARGB_8888,這個顏色模式色彩最細(xì)膩忠聚,顯示質(zhì)量最高赂蕴。但同樣的柳弄,占用的內(nèi)存也最大。 所以在對圖片效果不是特別高的情況下使用RGB_565(565沒有透明度屬性)
圖片大小邊界壓縮
直接使用ImageView顯示bitmap會占用較多資源概说,特別是圖片較大的時候语御,可能導(dǎo)致崩潰。
使用BitmapFactory.Options設(shè)置inSampleSize, 這樣做可以減少對系統(tǒng)資源的要求席怪。
屬性值inSampleSize表示縮略圖大小為原始圖片大小的幾分之一,即如果這個值為2纤控,則取出的縮略圖的寬和高都是原始圖片的1/2挂捻,圖片大小就為原始大小的1/4。
圖片OOM的原理:
假設(shè)一張圖片的寬高為2600 * 1800 像素船万,每個像素是ARGB_8888,則其直接拉進(jìn)內(nèi) 存刻撒,占用的內(nèi)存大小為:
2600 * 1800 * 4byte = 18720000byte = 17.8M
若展示此圖片的ImageView大小僅為260 * 180px,則加載這么大的圖片是沒什么意義的耿导,經(jīng)計(jì)算声怔,壓縮比為10(2600 / 260),即inSampleSize = 10舱呻;
經(jīng)過邊界壓縮后醋火,圖片的大小為:
260 * 180 * 4byte = 0.18M
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//開始讀入圖片悠汽,此時把options.inJustDecodeBounds 設(shè)回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此時返回bm為空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = 260f;//這里設(shè)置高度為260f
float ww = 180f;//這里設(shè)置寬度為180f
//縮放比。由于是固定比例縮放芥驳,只用高或者寬其中一個數(shù)據(jù)進(jìn)行計(jì)算即可
int be = 1;//be=1表示不縮放
if (w > h && w > ww) {//如果寬度大的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//設(shè)置縮放比例
//重新讀入圖片柿冲,注意此時已經(jīng)把options.inJustDecodeBounds 設(shè)回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//壓縮好比例大小后再進(jìn)行質(zhì)量壓縮
}
圖片回收
使用Bitmap過后,就需要及時的調(diào)用Bitmap.recycle()方法來釋放Bitmap占用的內(nèi)存空間兆旬,而不要等Android系統(tǒng)來進(jìn)行釋放假抄。
// 先判斷是否已經(jīng)回收
if(bitmap != null && !bitmap.isRecycled()){
// 回收并且置為null
bitmap.recycle();
bitmap = null;
}
System.gc();
常見圖片加載框架
Glide
目前用的這個
Univeral-Image-Loader
l 多線程下載圖片,圖片可以來源于網(wǎng)絡(luò)丽猬,文件系統(tǒng)宿饱,項(xiàng)目文件夾assets中以及drawable中等
l 支持隨意的配置ImageLoader,例如線程池脚祟,圖片下載器谬以,內(nèi)存緩存策略,硬盤緩存策略愚铡,圖片顯示選項(xiàng)以及其他的一些配置
l 支持圖片的內(nèi)存緩存蛉签,文件系統(tǒng)緩存或者SD卡緩存
l 支持圖片下載過程的監(jiān)聽
l 根據(jù)控件(ImageView)的大小對Bitmap進(jìn)行裁剪,減少Bitmap占用過多的內(nèi)存
l 較好的控制圖片的加載過程沥寥,例如暫停圖片加載碍舍,重新開始加載圖片,一般使用在ListView,GridView中邑雅,滑動過程中暫停加載圖片片橡,停止滑動的時候去加載圖片
l 提供在較慢的網(wǎng)絡(luò)下對圖片進(jìn)行加載
Picasso
l 使用ListView,GridView的時候淮野,自動檢測Adapter的重用捧书,取消下載,使用緩存
l 將圖像進(jìn)行變換骤星,以更好的適應(yīng)布局控件等经瓷,減小內(nèi)存開銷
l 進(jìn)行圖形變換,也可以寫自己的變換類洞难,但是必須實(shí)現(xiàn)Transformation接口
l 支持設(shè)置加載之前的圖片舆吮,和加載失敗后的圖片
l 支持加載資源文件的圖片
l 支持加載sdcard中的圖片文件
Fresco
FaceBook出品
Fresco綜合了之前圖片加載庫的優(yōu)點(diǎn)的基礎(chǔ)上利用本地代碼做了性能上的優(yōu)化