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

效果图:

压缩日志

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;
    }
}

最后小结

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

时间: 2024-10-24 11:03:50

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

PHP图片压缩类,高清无损直接用就ok啦

这个不完全是我自己写的-_-!,但是好用呀 <?php /** * Created by PhpStorm. * Note:文件介绍 * User: Lynly * Date: 2018/11/19 * Time: 14:33 */ class Imgcompress { private $src; private $image; private $imageinfo; private $percent = 0.5; /** * 图片压缩 * @param string $src 源图 * @p

Android的图片压缩类ThumbnailUtils

从Android 2.2开始系统新增了一个缩略图ThumbnailUtils类,位于framework包下的android.media.ThumbnailUtils位置,可以帮助我们从mediaprovider中获取系统中的视频或图片文件的缩略图,该类提供了三种静态方法可以直接调用获取. 1.extractThumbnail (source, width, height): Java代码   /** * * 创建一个指定大小的缩略图 * @param source 源文件(Bitmap类型) *

PHP 图片缩放类

<?php /** * 图片压缩类:通过缩放来压缩. * 如果要保持源图比例,把参数$percent保持为1即可. * 即使原比例压缩,也可大幅度缩小.数码相机4M图片.也可以缩为700KB左右.如果缩小比例,则体积会更小. * * 结果:可保存.可直接显示. */ class imgcompress{ private $src; private $image; private $imageinfo; private $percent = 0.5; /** * 图片压缩 * @param $sr

PHP实现图片压缩同时保持清晰度

图片太大是一个经常遇到的问题,为此很多人头疼.今天告诉大家如何实现PHP程序简单实现压缩: 图片原大小: 压缩后: 这是我自己实验的,可以处理多种图片格式. 当然图片原图越大,越能体现出压缩来. 现在附上代码: <?php /** * 图片压缩类:通过缩放来压缩. * 如果要保持源图比例,把参数$percent保持为1即可. * 即使原比例压缩,也可大幅度缩小.数码相机4M图片.也可以缩为700KB左右.如果缩小比例,则体积会更小. * * 结果:可保存.可直接显示. */ class imgc

php图片压缩-高清晰度

php高清晰度无损压缩 经常会用到把上传的大图片压缩,特别是体积,在微信等APP应用上,也默认都是有压缩的,那么,怎么样对图片大幅度压缩却仍能保持较高的清晰度呢? 压缩通常是有按比例缩放,和指定宽度压缩的,效果很不错,一个数码相机拍的4M图片,压缩后保持了较高的清晰度和原图宽高值,只有700K. 下面是代码(有两个文件,imgcompress.class.php 类,及compress.php) compress.php 1 <?php 2 require_once 'imgcompress.c

图片压缩的具体方法你知道多少

在我们日常的工作中,会接触到很多图片文件,而有些图片还需要经常的进行大小的改变,如果一个网站对于图片有大小的限制,那么我们就需要将我们手中的图片压缩变小,图片压缩的具体方法你知道多少呢?下面小编为大家介绍一个压缩图片的方法,希望可以帮到你!参考迅捷压缩软件1:电脑上安装图片压缩软件,压缩软件有三个压缩的功能.点击图片压缩就可以. 2:添加要进行压缩的图片,点击页面中的添加文件或者添加文件夹的按钮,选择目标文件. 3:点击选择一个合适的压缩选项,在添加文件下有输出格式和压缩选项的设置,根据实际情况

(转)Android学习-使用Async-Http实现图片压缩并上传功能

(转)Android学习-使用Async-Http实现图片压缩并上传功能 文章转载自:作者:RyaneLee链接:http://www.jianshu.com/p/940fc7ba39e1 让我头疼一个星期的图片批量上传服务器的问题最后受这篇文章的作者启发而解决,自己之前一直执着于通过uri地址找到图片然后上传图片,却没想过直接上传图片本身.感谢作者的博客和启发. 前言 (转载请注明出处,谢谢!) 最近在做一个小项目,项目中要实现上传图片到服务器,而这个例子是实现图片的尺寸压缩,将获取到的压缩图

图片压缩java工具类

package com.net.util; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import org

图片压缩,裁切,水印工具类

package default; import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream; import javax.imageio.ImageIO; import net.coobird.thumbnailator.Thumbnails;import net.coobird.thumbnailator.geometry.Po