1. 程式人生 > >android基於libjpeg-turbo的圖片壓縮框架

android基於libjpeg-turbo的圖片壓縮框架

Light

license
JCenter

a lightweight image compress framework for Android based on libJpeg.
一個基於libJpeg的壓縮圖片框架, 支援配合rxjava使用。
可以一行程式碼解決圖片下載->壓縮->顯示的過程。

demo效果

先展示一下壓縮前後的效果對比,以及檔案大小和佔用記憶體的大小
demo比較簡單,執行的時候請開啟sd卡許可權和相簿拍照許可權。

基本功能:

支援的壓縮型別:
File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable

  • 1:圖片的旋轉、縮放、平移操作
  • 2:非同步和同步壓縮處理
  • 3:同步壓縮
  • 4:可以配合RxJava2使用

    版本記錄:

    1.0.0 完成大致功能
    1.1.0 修復從uri獲取路徑錯誤的bug;
    增加ignoreSize的設定,以便用於壓縮圖片保持原尺寸;
    支援配合rxjava2使用;

    使用方法:

    android {
        ...
        ndk {
            abiFilters 'armeabi-v7a', 'armeabi', 'x86'
        }
    }
    
    //引入
    implementation 'com.noober.light:core:1.1.0'
    
    //如果要配合rxjava2,加入rxjava2的依賴
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
    

    設定壓縮引數:

    CompressArgs這個類用於設定每次所要壓縮到的指定的寬高以及壓縮質量。使用如下:

    CompressArgs args = new CompressArgs.Builder().width(width).height(height).quality(70).ignoreSize(false).build();
    
    引數說明:

    1.width: 要壓縮到的圖片的寬度,單位px
    2.height: 要壓縮到的圖片的高度,單位px
    3.quality: 壓縮質量, 可選範圍是0-100。
    4.ignoreSize: 是否要忽略壓縮後圖片寬高的限制, 如果設為true,壓縮的時候會根據原圖本身大小進行壓縮,設定的width和height就會失效,預設false。
    因為從網路下載圖片儲存到本地,中間預設會自動壓縮圖片,如果不想對圖片進行壓縮,並保持寬高的話,設定如下引數即可:

    CompressArgs args = new CompressArgs.Builder().quality(100).ignoreSize(true).build();
    
    預設引數:

    呼叫compress方法的時候也可以不初始化這個引數,框架會自動初始化一個預設的壓縮設定。

預設規則如下:
壓縮圖片的最大預設高度是螢幕高度;
圖片的最大寬度是螢幕寬度;
預設壓縮質量是85;
ignoreSize 為false。

設定全域性的壓縮引數,以便不需要每次都去設定:

建議在Application的onCreate中進行初始化,使用如下:

LightConfig lightConfig = new LightConfig();
lightConfig.setDefaultQuality(xx);
lightConfig.setMaxWidth(xx);
lightConfig.setMaxHeight(xx);
lightConfig.setMaxHeight(xx);
lightConfig.setNeedIgnoreSize(xx);
Light.getInstance().setConfig(lightConfig);

壓縮圖片,獲取Bitmap:images -> Bitmap

支援File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable這5種類型壓縮為Bitmap。

//String,Uri,Bytes,Bitmap,File -->bitmap
Bitmap bitmap = Light.getInstance().compress(path);
//args為CompressArgs壓縮引數,不傳入,即用預設引數
Bitmap bitmap = Light.getInstance().compress(path, args);
.....

壓縮圖片並且儲存到本地:images -> boolean

支援File,String,Uri,Bytes,Bitmap這5種類型儲存為檔案。
想對於壓縮成Bitmap的方法只是多了一個輸出路徑。

//images --> boolean //儲存圖片,返回值代表儲存是否成功
//img為要壓縮的圖片,args是壓縮引數,不傳即預設, outPath為輸出路徑
Light.getInstance().compress(img, args, outPath);
Light.getInstance().compress(img, outPath);
//支援型別Bitmap, Bytes, String, Resource, Uri, Drawable

配合RxJava2使用

關於配合RxJava2使用的類都在RxLight這個類中。
通過與rxJava的配合,一行程式碼就能實現從網路下載->壓縮->顯示,這個過程,非常的方便。

使用方法如下:

從網路獲取資源

RxLight會自動對圖片進行下載 -> 壓縮 -> 顯示或儲存到本地

從網路獲取資源 -> Bitmap:
//uri型別的網路資源
Flowable.just(uri).compose(RxLight.compressForUriHttp()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
List<Uri> urlList = new ArrayList<>();
....
Flowable.fromIterable(urlList).compose(RxLight.compressForUriHttp()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
//url型別的網路資源
Flowable.just(url).compose(RxLight.compressForStringHttp()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
List<String> urlList = new ArrayList<>();
....
Flowable.fromIterable(urlList).compose(RxLight.compressForStringHttp()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
//或者傳入自定義的壓縮引數只需要在compressForUriHttp() 和 compressForStringHttp()傳入CompressArgs即可
CompressArgs args = new CompressArgs();
....
Flowable.just(uri).compose(RxLight.compressForUriHttp(args)).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
從網路獲取資源 -> boolean(儲存到本地):

與上述方法類似,只需要compressForUri() 和 compressForString()傳入要儲存到的路徑即可。同樣支援uri和string的網路地址型別。

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pic.jpg";
Flowable.just(uri).compose(RxLight.compressForUriHttp(path)).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
//自定義壓縮引數
CompressArgs args = new CompressArgs();
....
Flowable.just(uri).compose(RxLight.compressForUriHttp(path, args)).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
通過本地資源非同步壓縮

同樣都支援 File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable這幾種型別

圖片資源 -> Bitmap

通過RxLight.compress()方法即可:

Flowable.just(image).compose(RxLight.compress()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
圖片資源 -> Boolean(儲存到本地):

通過RxLight.compress(outPath)方法即可:

Flowable.just(image).compose(RxLight.compress(outPath)).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));

其他

  • 1:MemoryComputeUtil工具類,獲取bitmap佔用記憶體的大小,返回值單位是kb。

     MemoryComputeUtil.getMemorySize(compressBitmap)
    
  • 2:關於so檔案的編譯,可以移步https://github.com/JavaNoober/LibJpegCompress
    如何去編譯,我在很久之前的寫過一個部落格介紹過:http://blog.csdn.net/qq_25412055/article/details/53878655

  • 3:MatrixUtil工具類
    可以很方便的對Bitmap進行放大縮小、旋轉、縮放、平移等處理,使用也很方便,支援Matrix的大部分方法。

    Bitmap result = new MatrixUtil.Build().scale(scaleSize, scaleSize).rotate(90f).bitmap(bitmap).build();
    

    總結

    版本還在逐步更新中,歡迎各位大佬star,以及提出建議。

    GitHub demo下載地址:https://github.com/JavaNoober/Light