如何使用Luban壓縮圖片
1.在項目中的build.gradle添加依賴(需要用到RxJava1.0)
2.在代碼中使用Luban壓縮方法
1)Listerner方式。傳入圖片File,調用設置壓縮監聽setCompressListerner方法,處理壓縮結果。
2)Rxjava方式,傳入圖片File,調用asObservable方法返回一個Observable觀察者對象,使用RxJava方式來處理壓縮結果。
3.Luban源碼分析
源碼中最主要的方法就是thirdCompress(File file),即如何計算得出理想的壓縮後寬高,以及圖片大小。
- 判斷圖片比例值,是否處於以下區間內;
- [1, 0.5625) 即圖片處於 [1:1 ~ 9:16) 比例範圍內
- [0.5625, 0.5) 即圖片處於 [9:16 ~ 1:2) 比例範圍內
- [0.5, 0) 即圖片處於 [1:2 ~ 1:∞) 比例範圍內
- 判斷圖片最長邊是否過邊界值;
- [1, 0.5625) 邊界值爲:1664 * n(n=1), 4990 * n(n=2), 1280 * pow(2, n-1)(n≥3)
- [0.5625, 0.5) 邊界值爲:1280 * pow(2, n-1)(n≥1)
- [0.5, 0) 邊界值爲:1280 * pow(2, n-1)(n≥1)
- 計算壓縮圖片實際邊長值,以第2步計算結果爲準,超過某個邊界值則:width / pow(2, n-1),height/pow(2, n-1)
- 計算壓縮圖片的實際文件大小,以第2、3步結果爲準,圖片比例越大則文件越大。
size = (newW * newH) / (width * height) * m;- [1, 0.5625) 則 width & height 對應 1664,4990,1280 * n(n≥3),m 對應 150,300,300;
- [0.5625, 0.5) 則 width = 1440,height = 2560, m = 200;
- [0.5, 0) 則 width = 1280,height = 1280 / scale,m = 500;注:scale爲比例值
- 判斷第4步的size是否過小
- [1, 0.5625) 則最小 size 對應 60,60,100
- [0.5625, 0.5) 則最小 size 都爲 100
- [0.5, 0) 則最小 size 都爲 100
- 將前面求到的值壓縮圖片 width, height, size 傳入壓縮流程,壓縮圖片直到滿足以上數值
源碼:
根據算法計算壓縮後的寬高以及圖片文件大小,在調用壓縮方法compress,傳入計算後的寬高以及圖片大小
開始進行壓縮,這裏分別執行了壓縮圖片大小compress方法,以及壓縮圖片質量saveImage方法
壓縮圖片至預期大小,配置BitmapFactory.Options中inSampleSize的值來壓縮圖片的寬高
圖片質量壓縮
4.主要代碼分析
清楚了第三檔壓縮的實現之後,再瞭解使用Luban壓縮時用到幾個方法:
get()、load(file)、putGear() 、setFileName()、setCompressListener()、launch()、asObservable()。
get(Context context)
首先調用的是get(this),傳入的是一個Context對象,調用私有的構造方法傳入一個File對象創建一個Luban對象;File對象生成調用的是getPhotoCacheDir方法,來指定緩存目錄。
路徑爲:app包名/cache/luban_disk_cache/文件名
load(File file)
public Luban load(File file) {
mFile = file;
return this;
}
這個方法比較容易理解,傳入的是我們圖片文件。
putGear(int gear)
public Luban putGear(int gear) {
this.gear = gear;
return this;
}
設置壓縮等級,源碼中只有兩種等級:FIRST_GEAR 和 THIRD_GEAR,傳入其他值無效。
private static final int FIRST_GEAR = 1;
public static final int THIRD_GEAR = 3;
setFileName(String fileName)
設置壓縮後的圖片名稱
public Luban setFilename(String filename) {
this.filename = filename;
return this;
}
setCompressListener(OnCompressListener listener)
設置壓縮監聽 OnCompressListener是一個接口,裏面有三個方法,對應三種狀態
public Luban setCompressListener(OnCompressListener listener) {
compressListener = listener;
return this;
}
public interface OnCompressListener {
/**
* Fired when the compression is started, override to handle in your own code
* 壓縮開始
*/
void onStart();
/**
* Fired when a compression returns successfully, override to handle in your own code
* 壓縮成功
*/
void onSuccess(File file);
/**
* Fired when a compression fails to complete, override to handle in your own code
* 壓縮失敗
*/
void onError(Throwable e);
}
lanuch()
開始壓縮,方法中使用的RxJava,根據設置的壓縮等級來壓縮圖片
asObservable()
使用這個方法的話,採用的Rxjava方式返回一個觀察者Observable。
public Observable<File> asObservable() {
if (gear == FIRST_GEAR)//判斷壓縮等級
return Observable.just(mFile).map(new Func1<File, File>() {
@Override
public File call(File file) {
return firstCompress(file); //調用第一檔壓縮方法
}
});
else if (gear == THIRD_GEAR)
return Observable.just(mFile).map(new Func1<File, File>() {
@Override
public File call(File file) {
return thirdCompress(file);// 調用第三檔壓縮方法
}
});
else return Observable.empty();
}
Luban存在的不足
1.不能很好的支持多圖片壓縮。(出現問題:多圖壓縮出現OOM)
2.項目使用中必須添加RxJava依賴。(已在測試項目中剔除掉RxJava依賴 「鏈接」