java图片压缩踩过的坑

java图片压缩踩过的坑

使用谷歌压缩工具Thumbnailator, 支持 图片缩放,区域裁剪,水印,旋转等,自行研究

         
          
                net.coobird
                thumbnailator
                0.4.8
            

保持图片尺寸不变,压缩大小,代码如下:

import net.coobird.thumbnailator.Thumbnails;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 图片压缩
 * @author
 */
@Slf4j
public class ImageCompressUtil {

    /**
     * 图片质量压缩,不改变大小
     * @param file
     * @param destPath
     * @param quality
     * @return
     * @throws IOException
     */
    public static String compressImage(File file, String destPath, float quality) {
        try {
            if (!file.exists()) {
                log.error("compressImage file not found 文件不存在");
                throw new FileNotFoundException("文件不存在");
            }

            File destFile = new File(destPath);
            if (!destFile.exists() && destFile.isDirectory()) {
                destFile.mkdirs();
            }

            String destFileUrl = destPath + File.separator + file.getName();
            Thumbnails.of(file)
                    .scale(1f)
                    .outputQuality(quality)
                    .toFile(destFileUrl);

            return destFileUrl;
        } catch (IOException e) {
            log.error("e");
            return "";
        }
    }

    /**
     * 压缩图片
     * @param httpUrl  图片地址
     * @param destPath
     * @return
     */
    public static String compressHttpUrl(String httpUrl, String destPath) {
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            InputStream input = connection.getInputStream();
            String destUrl = destPath + httpUrl.substring(httpUrl.lastIndexOf('/'));
            Thumbnails.of(input)
                    .scale(1f)
//                    .size(200, 500)   大小
//                    .outputQuality(0.5f) 质量
//                    .outputFormat("jpg") 图片格式
//                    .useOriginalFormat() 使用原文件格式
                    .toFile(destUrl);
            input.close();
            return destUrl;
        } catch (IOException e) {
            log.error("压缩图片异常");
            return "";
        }
    }

    public static void main(String[] args) {
//        String url = "";
//        String destPath = "C:/test/image";
//        compressImage(new File(url), destPath, 0.25f);
//        compressHttpUrl(url, destPath);
    }
}

利用上面的代码进行图片压缩时,非jpeg格式的图片会出现 Unsupported Image Type
在不改变代码基础可以借助第三方包解决:
引入twelvemonkeys 自动发现

        
            com.twelvemonkeys.imageio
            imageio-jpeg
            3.4.1
        

第二种方式,利用ImageIO和twelvemonkeys 进行压缩

/**
     * 图片质量压缩,大小不变
     * @param url
     * @param destFilePath
     * @param quality 0-1
     * @return
     */
    public static String compressImageQuality(String url, String destFilePath, float quality) {
        log.info("compressPictureByQuality 图片压缩|url:" + url + ";destFilePath:" + destFilePath
                + ";quality:" + quality);
        String destFileUrl = destFilePath + url.substring(url.lastIndexOf("/"));
        File destFileDir = new File(destFilePath);
        if (!destFileDir.exists()) {
            destFileDir.mkdirs();
        }

        File destFile = new File(destFileUrl);

        try (FileOutputStream out = new FileOutputStream(destFile)) {
            File file = new File(url);
            if (!file.exists()) {
                log.error("Not Found Img File,文件不存在");
                throw new FileNotFoundException("Not Found Img File,文件不存在");
            }

            log.info("图片压缩前大小" + file.length() + "字节");

            ImageWriteParam imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
            // 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
            imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            // 这里指定压缩的程度,参数quality是取值0~1范围内,
            imgWriteParams.setCompressionQuality(quality);
            imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
            // 使用RGB格式
            ColorModel colorModel = ColorModel.getRGBdefault();
            // 文件
            BufferedImage bufferedImage = ImageIO.read(file);
            // 指定压缩时使用的色彩模式
            imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel,
                    colorModel.createCompatibleSampleModel(
                            bufferedImage.getWidth(), bufferedImage.getHeight())));

            // 指定写图片的方式为 jpg
            ImageWriter imgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
            imgWriter.reset();
            // 必须先指定out值,才能调用write方法, ImageOutputStream可以通过任何OutputStream构造
            imgWriter.setOutput(ImageIO.createImageOutputStream(out));
            // 调用write方法,就可以向输入流写图片
            imgWriter.write(null, new IIOImage(bufferedImage, null, null),
                    imgWriteParams);
            log.info("结束设定压缩图片参数");
            bufferedImage.flush();
            out.flush();

            log.info("图片压缩后大小" + destFile.length() + "字节");
            return destFileUrl;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
踩坑说明:
DataInputStream dataInputStream;
Thumbnails.of(dataInputStream).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);
直接使用Thumbnails.of(dataInputStream) 会出现错误:UnsupportedFormatException: No suitable ImageReader found for source data
解决方法:
  1.把input存成本地文件,利用本地文件路径操作 Thumbnails.of(url)
  2.转换成BufferedImage
     BufferedImage bufferedImage = ImageIO.read(dataInputStream);
     Thumbnails.of(bufferedImage ).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);

更多压缩方式可以参考:https://blog.csdn.net/zmx729618/article/details/78729049

你可能感兴趣的:(java工具类,java,image)