1.通過Bitmap的compress()函數(shù)壓縮
先看一下官方文檔的解釋:
/**
* 將一個壓縮版本的Bitmap寫入到一個特定的OutputStream中。
* 如果返回true, 這個Bitmap可以通過BitmapFactory.decodeStream()將
* 對應的InputStream重新組建。提示: 不是所有的圖片格式都直接支持
*Bitmap config,所以有可能通過BitmapFactory 返回的Bitmap會有不同
*的圖形色深,和/或丟失每個像素的透明度 (e.g. JPEG只支持不透明
*像素).
*
* @param format 要壓縮的圖片格式
* @param quality 壓縮質(zhì)量0~100 ,對PNG無效,會直接忽略
* @param stream 寫壓縮數(shù)據(jù)的outputstream.
* @return 如果成功壓縮返回true.
*/
public boolean compress(CompressFormat format, int quality, OutputStream stream) {
}
CompressFormat參數(shù)支持三種格式的轉(zhuǎn)化,分別為JPEG,PNG,WEBP。其中PNG為無損格式,并不能壓縮。
我們通過一張旺財?shù)恼掌M行測試:

這是一張PNG圖片,大小為83.6kb
BitmapFactory.Options opts1 = new BitmapFactory.Options();
opts1.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.dog, opts1);
imageView1 = (ImageView) findViewById(R.id.image1);
imageView1.setImageBitmap(bitmap1);
File file = null;
FileOutputStream fos = null;
try {
file = new File("/storage/emulated/0/dog.png");
file.delete();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.JPEG, 70, stream);
fos = new FileOutputStream(file);
fos.write(stream.toByteArray());
} catch (Exception ex) {
file = null;
} finally {
//關閉資源
}
| 圖片大小 | 40 % | 70% | 100% |
|---|---|---|---|
| JPEG | 22.36 | 29.60kb | 115.14kb |
| PNG | 119.55kb | 119.55kb | 119.55kb |
| WEBP | 23.19kb | 26.78kb | 68.77kb |
通過測出的數(shù)據(jù)可以發(fā)現(xiàn)PNG格式是不會壓縮圖片大小的,和官方文檔說明的一樣。JPEG和WEBP在100%到70%之間圖片大小急劇變小,70%到40%卻變化很小。但圖片在內(nèi)存中的大小是沒有改變的,因為圖片占用內(nèi)存大小=圖片分辨率*單像素占用的字節(jié)(請看我的另一篇文章http://www.itdecent.cn/p/04457671dec4)。這里我們采用的色彩模式是ARGB_8888,單像素占用4個字節(jié),分辨率沒有改變,所以占用的內(nèi)存大小也不會改變,而圖片在硬盤中大小會改變是因為不同的壓縮算法(JPEG,WEBP)通過分析像素冗余進行了壓縮。
總結(jié):通過compress()壓縮的圖片在硬盤上的大小會改變,但在內(nèi)存中的大小是不會改變的。
2.通過采樣率壓縮
什么是采樣率壓縮?當我們加載一張圖片時,很可能這張圖片的分辨率是大于我們ImageView所需要的分辨率大小的,甚至超出了手機的分辨率。會占用很大的內(nèi)存。比如我們顯示的ImageView大小為100100,而我們要的加載的圖片分辨率是200200,那么只需要1/2的采樣率對圖片進行縮放就可以顯示這張圖片。如果一張圖片是100*150呢?
在BitmapFactory.Options里面有一個inSampleSize可以控制采樣率。
他的取值只能是2的冪次方。1/2表示縮放為原圖1/2,1/4表示縮放為原圖1/4。