源碼:GitHub:https://github.com/Nergal1/Luban
CSDN:http://download.csdn.net/detail/e491288767/9837653
目前做App開發總繞不開圖片這個元素。但是隨著手機拍照分辨率的提升,圖片的壓縮成為一個很重要的問題。單純對圖片進行裁切,壓縮已經有很多文章介紹。但是裁切成多少,壓縮成多少卻很難控制好,裁切過頭圖片太小,質量壓縮過頭則顯示效果太差。
Luban
是圖片壓縮工具,通過參考或者自創壓縮規則推求極致的壓縮效果 目前的版本壓縮效果主要參考微信。因為微信用戶量最大,如果壓縮后的圖片越接近微信則越被用戶接受。
效果與對比圖.png
先來看看 他的壓縮效果圖
拍照圖片的壓縮.jpg
接下來 說說他簡單的用法
截屏圖片的壓縮.jpg
導入
compile'io.reactivex:rxandroid:1.2.1'compile'io.reactivex:rxjava:1.1.6'compile'top.zibin:Luban:1.0.8'
使用
Luban.get(this).load(File)//傳人要壓縮的圖片.putGear(Luban.THIRD_GEAR)//設定壓縮檔次,默認三擋.setCompressListener(new OnCompressListener() {//設置回調@Overridepublic void onStart() {// TODO 壓縮開始前調用,可以在方法內啟動 loading UI}@Overridepublic void onSuccess(File file) {// TODO 壓縮成功后調用,返回壓縮后的圖片文件}@Overridepublic void onError(Throwable e) {// TODO 當壓縮過去出現問題時調用}? ? }).launch();//啟動壓縮
RxJava調用方式請自行隨意控制線程:
Luban.get(this)? ? ? ? .load(file)? ? ? ? .putGear(Luban.THIRD_GEAR)? ? ? ? .asObservable()? ? ? ? .subscribeOn(Schedulers.io())? ? ? ? .observeOn(AndroidSchedulers.mainThread())? ? ? ? .doOnError(newAction1() {? ? ? ? ? ? @Overridepublicvoidcall(Throwable throwable) {? ? ? ? ? ? ? ? throwable.printStackTrace();? ? ? ? ? ? }? ? ? ? })? ? ? ? .onErrorResumeNext(newFunc1>() {? ? ? ? ? ? @OverridepublicObservablecall(Throwable throwable) {returnObservable.empty();? ? ? ? ? ? }? ? ? ? })? ? ? ? .subscribe(newAction1() {? ? ? ? ? ? @Overridepublicvoidcall(Filefile) {// TODO 壓縮成功后調用,返回壓縮后的圖片文件}? ? ? ? }).launch();//啟動壓縮
算法步驟
目前的Luban
只是壓縮結果接近微信,自身的算法只是為了達到這個效果而設計的。
判斷圖片比例值,是否處于以下區間內;
[1, 0.5625) 即圖片處于 [1:1 ~ 9:16) 比例范圍內
[0.5625, 0.5) 即圖片處于 [9:16 ~ 1:2) 比例范圍內
[0.5, 0) 即圖片處于 [1:2 ~ 1:∞) 比例范圍內
判斷圖片最長邊是否過邊界值;
[1, 0.5625) 邊界值為:1664n(n=1), 4990n(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 = (newWnewH) / (widthheight) * 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 傳入壓縮流程,壓縮圖片直到滿足以上數值