功能这么齐全的图片压缩类,还有谁?

效果图:

功能这么齐全的图片压缩类,还有谁?_第1张图片

压缩日志

com.pengkv.moon I/--->: 原尺寸:1215*1080
com.pengkv.moon I/--->: 最终压缩比例:3倍/新尺寸:405*360

工具特点

 * 可以解析单张图片
 * 可以解析多张图片
 * 处理了压缩过程中OOM
 * 处理了部分手机照片旋转问题
 * 压缩后存储在缓存中,并可以清理
 * 压缩后返回缓存路径,方便上传
 * 可以从缓存路径读取出Bitmap,方便展示
 * 封装在2个类里,方便调用

使用方法

ImageCompressUtil.compressImageList(this, photos, new ImageCompressUtil.ProcessImgListCallBack() {
     @Override
     public void compressSuccess(final List<String> imgList) {
    //imgList为压缩后图片的路径
    }
});

压缩工具类

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import utils.ImageRotateUtil;

/** * Created by pengkv on 15/12/2. * 图片压缩工具类 */
public class ImageCompressUtil {

    private static List<String> mImageList = new ArrayList<>();// 临时图片集合
    private static String mImagePath = ""; // 单个临时图片
    public static String cachePath = "";
    public static int reqWidth = 320;
    public static int reqHeight = 480;

    //压缩单张图片方法
    public static void compressImage(final Context ctx, final String filePath, final ProcessImgCallBack callBack) {
        mImagePath = "";//清空路径

        new Thread(new Runnable() {
            @Override
            public void run() {
                //如果路径是图片,则进行压缩
                if (isImage(filePath)) {
                    mImagePath = compress(ctx, filePath);
                }
                callBack.compressSuccess(mImagePath);
            }
        }).start();
    }

    //压缩图片集合方法
    public static void compressImageList(final Context ctx, final List<String> fileList, final ProcessImgListCallBack callBack) {
        mImageList.clear();//清空集合
        if (fileList == null || fileList.isEmpty()) {
            callBack.compressSuccess(mImageList);
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                String tempPath = "";
                for (String imagePath : fileList) {
                    if (isImage(imagePath)) {
                        tempPath = compress(ctx, imagePath);
                        mImageList.add(tempPath);
                    }
                }
                callBack.compressSuccess(mImageList);
            }
        }).start();

    }

    //图片压缩的方法
    public static String compress(Context ctx, String filePath) {

        if (TextUtils.isEmpty(filePath))
            return filePath;

        File file = new File(filePath);
        if (!file.exists())//判断路径是否存在
            return filePath;

        if (file.length() < 1)//文件是否为空
            return null;

        File tempFile = getDiskCacheDir(ctx);
        String outImagePath = tempFile.getAbsolutePath(); // 输出图片文件路径


        int degree = ImageRotateUtil.getBitmapDegree(filePath); // 检查图片的旋转角度

        //谷歌官网压缩图片
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

        // 旋转:这步处理主要是为了处理三星手机拍的照片
        if (degree > 0) {
            bitmap = ImageRotateUtil.rotateBitmapByDegree(bitmap, degree);
        }

        // 写入文件
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(tempFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
            fos.flush();
            fos.close();
            bitmap.recycle();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return filePath;
        }

        return outImagePath;
    }


    /** * 计算压缩比例值 * 按照2、3、4...倍压缩 * * @param options 解析图片的配置信息 * @param reqWidth 所需图片压缩尺寸最小宽度 * @param reqHeight 所需图片压缩尺寸最小高度 * @return */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int picheight = options.outHeight;
        final int picwidth = options.outWidth;
        Log.i("--->", "原尺寸:" + picwidth + "*" + picheight);

        int targetheight = picheight;
        int targetwidth = picwidth;
        int inSampleSize = 1;

        if (targetheight > reqHeight || targetwidth > reqWidth) {
            while (targetheight >= reqHeight && targetwidth >= reqWidth) {
                inSampleSize += 1;
                targetheight = picheight / inSampleSize;
                targetwidth = picwidth / inSampleSize;
            }
        }

        Log.i("--->", "最终压缩比例:" + inSampleSize + "倍/新尺寸:" + targetwidth + "*" + targetheight);
        return inSampleSize;
    }


    //图片集合压缩成功后的回调接口
    public interface ProcessImgListCallBack {
        void compressSuccess(List<String> imgList);
    }

    //单张图片压缩成功后的回调接口
    public interface ProcessImgCallBack {
        void compressSuccess(String imgPath);
    }


    /** * 获取文件后缀名 * * @param fileName * @return 文件后缀名 */
    public static String getFileType(String fileName) {
        if (!TextUtils.isEmpty(fileName)) {
            int typeIndex = fileName.lastIndexOf(".");
            if (typeIndex != -1) {
                String fileType = fileName.substring(typeIndex + 1).toLowerCase();
                return fileType;
            }
        }
        return "";
    }

    /** * 判断是否是图片 * * @param fileName * @return 是否是图片类型 */
    public static boolean isImage(String fileName) {
        String type = getFileType(fileName);
        if (!TextUtils.isEmpty(type) && (type.equals("jpg") || type.equals("gif")
                || type.equals("png") || type.equals("jpeg")
                || type.equals("bmp") || type.equals("wbmp")
                || type.equals("ico") || type.equals("jpe"))) {
            return true;
        }
        return false;
    }

    /** * 将压缩后的图片存储在缓存中 */
    public static File getDiskCacheDir(Context ctx) {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = ctx.getExternalCacheDir().getPath();
        } else {
            cachePath = ctx.getCacheDir().getPath();
        }
        String uniqueName = System.currentTimeMillis() + "_tmp.jpg";
        return new File(cachePath + File.separator + uniqueName);
    }

    /** * 清理缓存文件夹 */
    public static void clearCache(Context ctx) {
        File file = new File(cachePath);
        File[] childFile = file.listFiles();
        if (childFile == null || childFile.length == 0) {
            return;
        }

        for (File f : childFile) {
            f.delete(); // 循环删除子文件
        }
    }


    /** * 从图片路径读取出图片 * * @param imagePath * @return */
    private Bitmap decodeFile(String imagePath) {
        Bitmap bitmap = null;
        try {
            File file = new File(imagePath);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = false;
            FileInputStream fis = new FileInputStream(file);
            bitmap = BitmapFactory.decodeStream(fis, null, options);
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}

图片旋转工具类

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.IOException;

/** * Created by pengkv on 15/12/2. * 图片旋转工具类 */
public class ImageRotateUtil {

    /** * 读取图片的旋转的角度 * * @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;
    }

    /** * 将图片按照某个角度进行旋转 * * @param bm 需要旋转的图片 * @param degree 旋转角度 * @return 旋转后的图片 */
    public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
        Bitmap returnBm = null;

        // 根据旋转角度,生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            //当内存溢出时,利用递归进行重新旋转
            while (returnBm == null) {
                System.gc();
                System.runFinalization();
                returnBm = rotateBitmapByDegree(bm, degree);
            }
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.recycle();
        }
        return returnBm;
    }
}

最后小结

可以更改类中的压缩参数,对图片压缩的质量进行调整

你可能感兴趣的:(压缩,图片,缓存,compress)