Android中圖片壓縮的三種實(shí)現(xiàn)方法
在 Android 開發(fā)中,圖片壓縮是一個(gè)重要的優(yōu)化手段,旨在提升用戶體驗(yàn)、減少網(wǎng)絡(luò)傳輸量以及降低存儲(chǔ)空間占用。以下是幾種主流的圖片壓縮方法,結(jié)合原理、使用場(chǎng)景和優(yōu)缺點(diǎn)進(jìn)行詳細(xì)解析。
一、質(zhì)量壓縮法
使用場(chǎng)景
開發(fā)者需要在保持圖片質(zhì)量的同時(shí)減小文件大小的場(chǎng)景。
是什么
質(zhì)量壓縮法通過(guò)降低圖片的壓縮質(zhì)量(如 JPEG 的壓縮率)來(lái)減小文件大小。這種方法不會(huì)改變圖片的分辨率(寬高不變),但會(huì)減少圖片的文件體積。
為什么選擇它
- 適用于需要保持較高圖片質(zhì)量但減少文件大小的場(chǎng)景。
- 常用于社交媒體應(yīng)用中的圖片上傳,確保圖片快速加載同時(shí)保持較好的視覺(jué)效果。
何時(shí)使用
- 當(dāng)需要在保持圖片質(zhì)量的同時(shí)減少文件大小時(shí)。
- 適用于網(wǎng)絡(luò)傳輸或存儲(chǔ)優(yōu)化場(chǎng)景。
如何實(shí)現(xiàn)
通過(guò)設(shè)置 Bitmap.CompressFormat 和壓縮質(zhì)量參數(shù)來(lái)實(shí)現(xiàn)。
代碼示例:
//傳入的參數(shù)為bitmap
private Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 第一次壓縮,質(zhì)量為 100(不壓縮)
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
// 循環(huán)壓縮直到滿足條件
while (baos.toByteArray().length / 1024 > 100) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
}
// 生成壓縮后的 Bitmap
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
return BitmapFactory.decodeStream(isBm);
}
注意:質(zhì)量壓縮需要按照個(gè)人需求去進(jìn)行調(diào)整,示例寫了100,沒(méi)有進(jìn)行壓縮,大家可以嘗試一下壓縮到50,然后跟原圖進(jìn)行一個(gè)對(duì)比。
優(yōu)缺點(diǎn)總結(jié)
優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡(jiǎn)單,代碼量少。
- 可以靈活控制壓縮質(zhì)量,適合對(duì)圖片質(zhì)量要求較高的場(chǎng)景。
缺點(diǎn):
- 在內(nèi)存中占用的大小不變(分辨率未變),可能導(dǎo)致內(nèi)存消耗較大。
- 高質(zhì)量壓縮可能導(dǎo)致圖片模糊。
二、采樣率壓縮法
使用者
開發(fā)者需要大幅減小圖片尺寸的場(chǎng)景,例如生成縮略圖或適應(yīng)不同屏幕分辨率。
是什么
采樣率壓縮法通過(guò)減少圖片的分辨率(降低像素?cái)?shù)量)來(lái)減小文件大小。通過(guò)設(shè)置 BitmapFactory.Options.inSampleSize,可以控制圖片的縮放比例。
為什么選擇它
- 能有效減少內(nèi)存占用和文件大小。
- 適用于需要生成縮略圖或適應(yīng)不同設(shè)備屏幕分辨率的場(chǎng)景。
何時(shí)使用
- 當(dāng)需要大幅減小圖片尺寸時(shí)。
- 適用于在內(nèi)存資源有限的設(shè)備上加載大圖片。
如何實(shí)現(xiàn)
通過(guò)設(shè)置 inSampleSize 來(lái)實(shí)現(xiàn)采樣率壓縮。
代碼示例:
//傳入的參數(shù)為圖片的路徑
private Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 僅讀取圖片的寬高,不加載圖片到內(nèi)存
newOpts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
// 根據(jù)需求計(jì)算采樣率
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = 1280f; // 目標(biāo)高度
float ww = 720f; // 目標(biāo)寬度
int be = 1;
// 根據(jù)寬度或高度計(jì)算采樣率
if (w > h && w > ww) {
be = (int) (w / ww);
} else if (h > w && h > hh) {
be = (int) (h / hh);
}
newOpts.inSampleSize = be;
// 重新加載圖片
return BitmapFactory.decodeFile(srcPath, newOpts);
}
優(yōu)缺點(diǎn)總結(jié)
優(yōu)點(diǎn):
- 能顯著減少內(nèi)存占用和文件大小。
- 支持靈活的縮放比例設(shè)置。
缺點(diǎn):
- 可能導(dǎo)致圖片模糊(尤其是高分辨率圖片)。
- 需要手動(dòng)計(jì)算采樣率,增加了開發(fā)復(fù)雜度。
三、縮放法
使用者
開發(fā)者需要精確控制圖片尺寸的場(chǎng)景,例如生成特定比例的縮略圖。
是什么
縮放法通過(guò)調(diào)整圖片的尺寸(縮放寬高)來(lái)減小文件大小。通過(guò) Bitmap.createBitmap() 和 Canvas 繪制縮放后的圖片,可以實(shí)現(xiàn)尺寸壓縮。
為什么選擇它
- 適用于需要精確控制圖片尺寸的場(chǎng)景。
- 能夠生成符合特定比例的縮略圖或適配圖片。
何時(shí)使用
- 當(dāng)需要生成特定尺寸的縮略圖或適配不同設(shè)備屏幕時(shí)。
- 適用于需要精確控制圖片比例的場(chǎng)景。
如何實(shí)現(xiàn)
通過(guò)創(chuàng)建 Canvas 和 Matrix 進(jìn)行縮放。
代碼示例:
//傳入的參數(shù)為bitmpa,還有需要保存文件的路徑
public static void compressBitmapToFile(Bitmap bmp, File file) {
int ratio = 2; // 縮放比例
// 創(chuàng)建縮放后的 Bitmap
Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio,
bmp.getHeight() / ratio,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
canvas.drawBitmap(bmp, null, rect, null);
// 壓縮并保存到文件
ByteArrayOutputStream baos = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.JPEG, 100, baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
注意:上面的示例方法中,可以直接去掉file的相關(guān)邏輯,返回result就可以了
public static Bitmap compressBitmap(Bitmap bmp) {
int ratio = 2; // 縮放比例
// 創(chuàng)建縮放后的 Bitmap
Bitmap result = Bitmap.createBitmap(
bmp.getWidth() / ratio,
bmp.getHeight() / ratio,
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
canvas.drawBitmap(bmp, null, rect, null);
return result; // 直接返回縮放后的 Bitmap
}
優(yōu)缺點(diǎn)總結(jié)
優(yōu)點(diǎn):
- 支持精確控制縮放比例。
- 適用于生成適配不同設(shè)備的圖片。
缺點(diǎn):
- 多次縮放可能導(dǎo)致圖片失真。
- 實(shí)現(xiàn)相對(duì)復(fù)雜,需要更多的代碼量。
四、方法優(yōu)缺點(diǎn)對(duì)比總結(jié)
| 方法類型 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|
| 質(zhì)量壓縮法 | - 保持圖片質(zhì)量較高 - 實(shí)現(xiàn)簡(jiǎn)單 | - 內(nèi)存占用不變 - 高壓縮率可能導(dǎo)致模糊 |
| 采樣率壓縮法 | - 顯著減少文件大小和內(nèi)存占用 - 支持靈活設(shè)置采樣率 | - 可能導(dǎo)致圖片模糊 - 需要手動(dòng)計(jì)算采樣率 |
| 縮放法 | - 精確控制圖片尺寸 - 適用于生成適配圖片或縮略圖 | - 多次縮放可能導(dǎo)致失真 - 實(shí)現(xiàn)相對(duì)復(fù)雜 |
五、適用場(chǎng)景總結(jié)
- 質(zhì)量壓縮法:適用于需要保持較高圖片質(zhì)量但減少文件大小的場(chǎng)景,例如社交媒體圖片上傳。
- 采樣率壓縮法:適用于需要生成縮略圖或適應(yīng)不同屏幕分辨率的場(chǎng)景,例如在相冊(cè)應(yīng)用中加載大圖片。
- 縮放法:適用于需要精確控制圖片尺寸的場(chǎng)景,例如生成特定比例的縮略圖。
通過(guò)以上幾種方法的結(jié)合使用,可以根據(jù)具體需求選擇合適的壓縮策略,從而優(yōu)化 Android 應(yīng)用的性能和用戶體驗(yàn)。
以上就是Android中圖片壓縮的三種實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于Android圖片壓縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android垃圾回收機(jī)制解決內(nèi)存泄露問(wèn)題
這篇文章主要介紹了Android垃圾回收機(jī)制解決內(nèi)存泄露問(wèn)題的相關(guān)資料,需要的朋友可以參考下2016-02-02
Android kotlin+協(xié)程+Room數(shù)據(jù)庫(kù)的簡(jiǎn)單使用
這篇文章主要介紹了Android kotlin+協(xié)程+Room數(shù)據(jù)庫(kù)的簡(jiǎn)單使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
解決AMD無(wú)法使用Android studio問(wèn)題
這篇文章主要介紹了AMD無(wú)法使用Android studio解決方法,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
Android自定義View實(shí)現(xiàn)波浪動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)波浪動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
Android實(shí)現(xiàn)類似網(wǎng)易新聞選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果
這篇文章主要介紹了Android實(shí)現(xiàn)類似網(wǎng)易新聞選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
Android ShareSDK快速實(shí)現(xiàn)分享功能
這篇文章主要介紹了Android ShareSDK快速實(shí)現(xiàn)分享功能的相關(guān)資料,需要的朋友可以參考下2016-02-02
Android Studio使用教程(五):Gradle命令詳解和導(dǎo)入第三方包
這篇文章主要介紹了Android Studio使用教程(五):Gradle命令詳解和導(dǎo)入第三方包,本文講解了導(dǎo)入Android Studio、Gradle常用命令等內(nèi)容,需要的朋友可以參考下2015-05-05

