Android 圖片壓縮器

概述

Android 圖片壓縮器:一款高效的圖片壓縮器庫,支持批量壓縮,異步壓縮、多線程多任務壓縮,壓縮比設置等特性。

詳細

1、android圖片壓縮器特色

1.壓縮比能夠選擇控制。html

2.高效率的多線程壓縮java

3.支持批量壓縮android

2、實現過程

2.1 壓縮任務線程類多線程

該類是用於實現多線程壓縮任務,利用CountDownLatch 計數計數實現多線程任務等待機制,核心代碼以下:異步

/**
 * Created by caizhiming on 2016/6/2.
 * 圖片壓縮任務線程
 */
public class CompressTask extends Thread{
    CountDownLatch mLatch;
    Boolean mRet;
    String mInFilePath;
    String mOutFilePath;
    boolean mIsNeedCompress;
    public CompressTask(CountDownLatch latch,Boolean ret,String inFilePath,String outFilePath,boolean isNeedCompress){
        mLatch = latch;
        mRet = ret;
        mInFilePath = inFilePath;
        mOutFilePath = outFilePath;
        mIsNeedCompress = isNeedCompress;
    }
    @Override
    public void run() {
        if(mIsNeedCompress) {
            mRet = NativeBitmapUtil.syncCompressBitmap(mInFilePath,mOutFilePath);
            mLatch.countDown();
        }else{
            mRet = true;
            mLatch.countDown();
        }
    }
}

2.2 圖片圖像工具類ide

該工具類主要對Bitmap圖像處理作了一些封裝,好比Bitmap旋轉,獲取旋轉角度等,核心代碼以下:工具

/**
 * 獲取旋轉後的圖片
 * @param path
 * @return
 */
public static Bitmap getRotateBitmapByPath(String path) {
    return rotateBitmapByDegree(BitmapFactory.decodeFile(path), getBitmapDegree(path));
}
/**
 * 獲取旋轉後的圖片
 * @param path
 * @return
 */
public static Bitmap getRotateBitmapByPath(String path,final int maxSize) {
    BitmapFactory.Options  options= new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);
    options.inSampleSize = BitmapUtils.calculateInSampleSize(options,maxSize,maxSize);
    options.inJustDecodeBounds = false;
    return rotateBitmapByDegree(BitmapFactory.decodeFile(path,options), getBitmapDegree(path));
}
/**
 * 將圖片按照某個角度進行旋轉
 *
 * @param bm
 *            須要旋轉的圖片
 * @param degree
 *            旋轉角度
 * @return 旋轉後的圖片
 */
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
    Bitmap returnBm = null;

    // 根據旋轉角度,生成旋轉矩陣
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    try {
        if (bm != null) {
            // 將原始圖片按照旋轉矩陣進行旋轉,並獲得新的圖片
            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        }
    } catch (OutOfMemoryError e) {
    }
    if (returnBm == null) {
        returnBm = bm;
    }
    if (bm != returnBm) {
        bm.recycle();
    }
    return returnBm;
}
/**
 * 讀取圖片的旋轉的角度
 *
 * @param path
 *            圖片絕對路徑
 * @return 圖片的旋轉角度
 */
public static int getBitmapDegree(String path) {
    int degree = 0;
    try {
        // 從指定路徑下讀取圖片,並獲取其EXIF信息
        ExifInterface exifInterface = new ExifInterface(path);
        // 獲取圖片的旋轉信息
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return degree;
}

2.3 壓縮器類的實現post

該功能類只要實現多線程文件壓縮功能,支持異步壓縮單張圖片和多張圖片等特性。線程

2.3.1首先定義圖片壓縮狀態監聽接口,以下:code

/**
 * 圖片壓縮監聽器
 */
public interface ImageCompressListener {
    void onSuccess(List<String> outFilePathList);

    void onFailure(String message);
}

2.3.2 其次提供是否壓縮判斷方案:

public static long MAX_FILE_SIZE = 1024 * 1024;
/**
 * 是否壓縮圖片:大於 1280*1280的 圖片 須要壓縮 或者 大小大於1M
 * @param inFilePath
 * @return isNeedCompress
 */
public static boolean isNeedCompress(String inFilePath){
    boolean ret = true;
    File file = new File(inFilePath);
    if(file != null && file.exists()){
        BitmapFactory.Options  options= new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(inFilePath,options);
        if(options.outWidth <= BitmapUtil.MAX_SIZE
                && options.outHeight <= BitmapUtil.MAX_SIZE){
            ret = false;
        }
        if(file.length() > MAX_FILE_SIZE){
            ret = true;
        }
    }
    return ret;
}

2.3.3 最後實現異步壓縮功能,核心代碼以下:

/**
 * 異步壓縮多張圖片
 * @param inFilePathList:須要壓縮的圖片的路徑列表
 * @param outList:壓縮後輸出的新圖片的路徑列表
 * @param listener:壓縮監聽器
 */
public static void compress(final List<String> inFilePathList, final List<String> outList
        , final ImageCompressListener listener) {
    final List<String> outFilePathList = (outList == null) ? createOutFilePathList(inFilePathList) : outList;
    new AsyncTask<Void, Void, Boolean>() {
        @Override
        protected Boolean doInBackground(Void... params) {
            boolean isSuccess = true;
            CountDownLatch singal = new CountDownLatch(inFilePathList.size());
            List<Boolean> retList = new ArrayList<>();
            for (int i = 0; i < inFilePathList.size(); i++) {
                retList.add(i, Boolean.TRUE);
                boolean isNeedCompress = isNeedCompress(inFilePathList.get(i));
                if(!isNeedCompress){
                    outFilePathList.set(i,inFilePathList.get(i));
                }
                CompressTask compressTask = new CompressTask(singal, retList.get(i)
                        , inFilePathList.get(i), outFilePathList.get(i),isNeedCompress);
                compressTask.start();
            }
            try {
                singal.await();
                for (Boolean ret : retList) {
                    if(!ret) isSuccess = false;
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
                isSuccess = false;
            }finally {
                if(!isSuccess) {
                    String failErrorMsg = "";
                    for(int i =0;i < retList.size();i++){
                        if(!retList.get(i)){
                            failErrorMsg += "\nCompress error: "+inFilePathList.get(i);
                        }
                    }
                }
                return isSuccess;
            }
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if(listener != null){
                if(result) {
                    listener.onSuccess(outFilePathList);
                    for(String path :outFilePathList){
                        Log.v("czm","outFilePath="+path);
                    }
                }else{
                    listener.onFailure("圖片壓縮失敗!!");
                }
            }
        }
    }.execute();
}

3、使用方法

3.1 使用該壓縮器很簡單,直接一個方法搞定:

    List<String> srcFilePathList = new ArrayList<>();
    List<String> outputFilePathList = new ArrayList<>();
    //默認壓縮方法
    XCImageCompressor.compress(srcFilePathList, new XCImageCompressor.ImageCompressListener() {
        @Override
        public void onSuccess(List<String> outFilePathList) {

        }

        @Override
        public void onFailure(String message) {

        }
    });
    
    //支持壓縮後的輸出目錄的壓縮方法
    XCImageCompressor.compress(srcFilePathList, outputFilePathList,new XCImageCompressor.ImageCompressListener() {
        @Override
        public void onSuccess(List<String> outFilePathList) {

        }

        @Override
        public void onFailure(String message) {

        }
    });

4、源碼目錄截圖

111.png

 

注:本文著做權歸做者,由demo大師發表,拒絕轉載,轉載須要做者受權

相關文章
相關標籤/搜索