java 压缩图片大小

提供两个方法
1.压缩网络路径的图片
2.压缩本地路径的图片

直接复制PicUtils类就即用,具体看代码啦。

package com.qiyi.util;

import com.xiruo.medbid.util.OssFileUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.log4j.Logger;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Map;

public class PicUtils {
    private static final Logger logger = Logger.getLogger(PicUtils.class);

    public static void main(String[] args) throws Exception {
        String url = "https://mbnprodfile.oss-cn-shenzhen.aliyuncs.com/xxxxx/5868500806729729.jpg";
        System.err.println(zipPic(url, 180));
		
		String pc_url = "C:\\Users\\windows\\Desktop\\图\\5868500806729729.jpg";
        System.err.println(zipPicPC(url, 180));

    }


    /**
     * 根据指定大小压缩图片
     *
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小,单位kb
     * @param imageId     影像编号
     * @return 压缩质量后的图片字节数组
     */
    public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId) {
        if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / 1024);
        try {
            while (imageBytes.length > desFileSize * 1024) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
            }
            logger.info("【图片压缩】imageId={" + imageId + "} | 图片原大小={" + srcSize / 1024 + "}kb | 压缩后大小={" + imageBytes.length / 1024 + "}kb");
        } catch (Exception e) {
            logger.error("【图片压缩】msg=图片压缩失败!", e);
        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }


    private static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度,如果为-1,代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }


    /**
     * 压缩图片
     *
     * @param picUrl 图片url
     * @param size   单位kb
     * @return 新图片url
     */
    public static String zipPic(String picUrl, Integer size) throws Exception {
        URL url = new URL(picUrl);
        //打开链接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置请求方式为"GET"
        conn.setRequestMethod("GET");
        //超时响应时间为5秒
        conn.setConnectTimeout(5 * 1000);
        //通过输入流获取图片数据
        InputStream inStream = conn.getInputStream();
        //得到图片的二进制数据,以二进制封装得到数据,具有通用性
        byte[] bytes = readInputStream(inStream);
        BigDecimal fileSize = new BigDecimal(bytes.length);
        BigDecimal kilobyte = new BigDecimal(1024);
        float returnValue = fileSize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
        if (returnValue <= size) {
            return picUrl;
        }
        //少于指定size
        bytes = PicUtils.compressPicForScale(bytes, size, "x");
        InputStream inputStream = new ByteArrayInputStream(bytes);
		// 拿到 inputStream 怎么保存都可以啦 - 这里是上传到阿里云oss
        Map result = OssFileUtils.upload(IDUtils.nextIdText() + ".jpg", inputStream);
        String newUrl = result.get("filePath").toString();
        return newUrl;
    }

    /**
     * 压缩本地图片,给本地
	 * @param picUrl 本地图片url
     * @param size   单位kb
     * @return 本地图片url
     */
    public static String zipPicPC(String picUrl, Integer size) throws Exception {
        File file = new File(picUrl);
        //通过输入流获取图片数据
        InputStream inStream = new FileInputStream(file);
        //得到图片的二进制数据,以二进制封装得到数据,具有通用性
        byte[] bytes = readInputStream(inStream);
        BigDecimal fileSize = new BigDecimal(bytes.length);
        BigDecimal kilobyte = new BigDecimal(1024);
        float returnValue = fileSize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
        if (returnValue <= size) {
            return picUrl;
        }
        //少于指定size
        bytes = PicUtils.compressPicForScale(bytes, size, "x");
        InputStream inputStream = new ByteArrayInputStream(bytes);

        inputstreamtofile(inputStream, file);
        return file.getPath();
    }

    public static void inputstreamtofile(InputStream ins, File file) throws Exception {
        OutputStream os = new FileOutputStream(file);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
    }



}

你可能感兴趣的:(网络,springboot,文件,java,log4j,apache)