thumbnailator图片压缩和碰见的问题修复

项目:文件存储系统

需求: 需要开发一个图片压缩接口,需要对图片进行按比例压缩

方案:选择用thumbnailator来实现图片压缩,

/**
     * 压缩图片方法
     * @param in
     * @throws Exception
     */
    public static BufferedImage compressionImage(InputStream in ,float quality)throws Exception{
        //默认图片质量因子
        if (quality == 0) {
            quality = 0.6f;
        }
        BufferedImage bufferedImage = ImageIO.read(in);
        double scale=1/computeSize(bufferedImage);
        Thumbnails.of(bufferedImage);
        BufferedImage thumbnail= Thumbnails.of(bufferedImage)
                .outputFormat(Constant.IMAGE_FORMAT_JPEG)
                .scale(scale)
                .outputQuality(quality)
                .asBufferedImage();
        in.close();
        return thumbnail;
    }

使用:

BufferedImage bufferedImage= ImageUtil.compressionImage(inputStream, fileDownloadVo.getQuality());
            String imageSize= ImageUtil.getImageMeasure(bufferedImage);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, Constant.IMAGE_FORMAT_JPEG,byteArrayOutputStream);
            byte[] bytes = byteArrayOutputStream.toByteArray();
            long fileSize = bytes.length;

问题:

测试出现了图片背景颜色会发生变化,不符合要求,

问题原因:

  1. Java上传图片时,对某些图片进行缩放、裁剪或者生成缩略图时会蒙上一层红色,经过检查只要经过ImageIO.read()方法读取后再保存,该图片便已经变成红图。因此,可以推测直接原因在于ImageIO.read()方法加载图片的过程存在问题
  2. 经过查阅得知ImageIO.read()方法读取图片时可能存在不正确处理图片ICC信息的问题,ICC为JPEG图片格式中的一种头部信息(进行校验图片颜色的信息),导致渲染图片前景色时蒙上一层红色。
  3. 发现报红的图片比不报红的图片头文件缺少一段信息

解决方案:

使用阿里巴巴simpleimage
SimpleImage github地址:https://github.com/alibaba/simpleimage
依赖jar:commons-io-2.4.jar
commons-lang.jar
commons-logging-1.1.1.jar
jai_codec-1.1.3.jar(这个jar包可以在git源码里下载,需要手动添加到项目)
jai_core-1.1.3.jar(这个jar包可以在git源码里下载,需要手动添加到项目)

第二版代码:

/**
     * 压缩图片方法
     * @param in
     * @throws Exception
     */
    public static BufferedImage compressionImage(InputStream in ,float quality)throws Exception{
        //默认图片质量因子
        if (quality == 0) {
            quality = 0.6f;
        }
        ImageWrapper imageWrapper = ImageReadHelper.read(in);
        BufferedImage bufferedImage = imageWrapper.getAsBufferedImage();
        double scale=1/computeSize(bufferedImage);
        Thumbnails.of(bufferedImage);
        BufferedImage thumbnail= Thumbnails.of(bufferedImage)
                .outputFormat(Constant.IMAGE_FORMAT_JPEG)
                .scale(scale)
                .outputQuality(quality)
                .asBufferedImage();
        in.close();
        return thumbnail;
    }

使用

BufferedImage bufferedImage= ImageUtil.compressionImage(inputStream, fileDownloadVo);
String imageSize= ImageUtil.getImageMeasure(bufferedImage);
ImageWrapper imageWrapper = new ImageWrapper(bufferedImage);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageWriteHelper.write(imageWrapper, byteArrayOutputStream, ImageFormat.JPEG, new WriteParameter());
byte[] bytes = byteArrayOutputStream.toByteArray();
long fileSize = bytes.length;

第二版测试:

图片变色问题修复,出现新的问题,图片压缩后图片变大了,557KB的图片变成了900多KB,这就尴尬了

问题排查:

通过排查,问题出现在ImageWriteHelper.write(imageWrapper, byteArrayOutputStream, ImageFormat.JPEG, new WriteParameter());这边具体什么原因我不知道,如果有知道的大佬麻烦告知下,

解决方案

默认的采样率是93,设置成60后,557KB的图片变成了440KB,符合要求

第三版代码:

BufferedImage bufferedImage= ImageUtil.compressionImage(inputStream, fileDownloadVo);
String imageSize= ImageUtil.getImageMeasure(bufferedImage);
//设置采样参60.默认93,太大的图片大小会变大不符合压缩要求
ImageWrapper imageWrapper = new ImageWrapper(bufferedImage,60);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageWriteHelper.write(imageWrapper, byteArrayOutputStream, ImageFormat.JPEG, new WriteParameter());
byte[] bytes = byteArrayOutputStream.toByteArray();
long fileSize = bytes.length;

总结:

网络上对于图片压缩过程中会出现的问题记录和解决方案比较少,这边记录下也分享出来,希望你们有帮助,如果有问题的地方麻烦各位大佬指正.

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值