DuKBitmapImages 圖片壓縮處理技術

Android圖片壓縮上傳系列

*壓縮中的問題:

--圖片壓縮上若是存在問題,勢必形成消耗大量的流量,下載圖片的速度慢等影響產品性能,那麼如何解決?請看下面:

  1. 壓縮圖片一共多少張?一塊兒壓縮?分開壓縮?尺寸?
  2. 壓縮後的圖片保存的路徑?
  3. 對於多圖壓縮性能處理的問題?併發or線性處理?
  4. 能不能使用service來進行壓縮處理,是local(本地)仍是remote(遠程)的方式來啓動service?
  5. 若是須要壓縮的圖片很是多,如何使用線程池來處理?
 

 其實作過圖片壓縮的朋友應該知道,這一塊的技術點就那麼幾個,按照邏輯處理起來也是不同的效果,主要是關注處理出來的圖片的尺寸和質量。java

* 等比壓縮

這裏首先按照原始圖片的寬高比,等比計算出sampleSize。代碼網上也有相關,這裏貼出方法的代碼:git

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcImagePath, options);
//根據原始圖片的寬高比和指望的輸出圖片的寬高比計算最終輸出的圖片的寬和高
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float maxWidth = outWidth;//指望輸出的圖片寬度
float maxHeight = outHeight;//指望輸出的圖片高度
float srcRatio = srcWidth / srcHeight;
float outRatio = maxWidth / maxHeight;
float actualOutWidth = srcWidth;//最終輸出的圖片寬度
float actualOutHeight = srcHeight;//最終輸出的圖片高度

if (srcWidth > maxWidth || srcHeight > maxHeight) {
    if (srcRatio < outRatio) {
        actualOutHeight = maxHeight;
        actualOutWidth = actualOutHeight * srcRatio;
    } else if (srcRatio > outRatio) {
        actualOutWidth = maxWidth;
        actualOutHeight = actualOutWidth / srcRatio;
    } else {
        actualOutWidth = maxWidth;
        actualOutHeight = maxHeight;
    }
}
//計算sampleSize
options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight);

 

 *圖片質量壓縮

ANDORID API:github

public boolean compress(CompressFormat format, int quality, OutputStream stream)

方法以下:web

//進行有損壓縮
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options_ = 100;
actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//質量壓縮方法,把壓縮後的數據存放到baos中 (100表示不壓縮,0表示壓縮到最小)

int baosLength = baos.toByteArray().length;
while (baosLength / 1024 > maxFileSize) {//循環判斷若是壓縮後圖片是否大於maxMemmorrySize,大於繼續壓縮
    baos.reset();//重置baos即讓下一次的寫入覆蓋以前的內容
    options_ = Math.max(0, options_ - 10);//圖片質量每次減小10
    actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//將壓縮後的圖片保存到baos中
    baosLength = baos.toByteArray().length;
    if (options_ == 0)//若是圖片的質量已降到最低則,再也不進行壓縮
        break;
}

那麼有個耗時問題,這裏的開個線程去處理這件事。

爲了達到最佳的壓縮結果,能夠將上面兩種方案同時進行。若是壓縮消耗的時間很長,須要將壓縮過程放入後臺線程中執行。
多線程

這裏實現的功能有:併發

  1. 打開攝像頭進行拍照處理(旋轉、截取)
  2. 處理後的圖片保存到指定位置
  3. 壓縮後的照片保存到指定目錄下
  4. 使用AsyncTask執行壓縮操做,處理耗時問題
  5. 顯示壓縮後的照片及其相關信息到前臺activity


另外,如何結合使用service和多線程會在下篇文章具體說明。
性能

開源github地址以下:
DuKBitmapImages
spa


歡迎你們訪問並star,若是有任何問題能夠在評論中加以提問,謝謝~~
線程

相關文章
相關標籤/搜索