TypechoJoeTheme

香草物语

统计
登录
用户名
密码
/
注册
用户名
邮箱
输入密码
确认密码

使用thumbnailator实现图片压缩

Laughing博主
2024-07-04
/
0 评论
/
463 阅读
/
543 个字
/
百度已收录
07/04
本文最后更新于2024年07月04日,已超过76天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

Thumbnailator是一个用于Java的强大的图片处理库,主要用于创建、缩放和裁剪图片的缩略图。它设计得既简单又功能强大,提供了一系列丰富的特性:

  1. 尺寸调整Thumbnailator能够根据指定的宽度或高度来调整图片大小。
  2. 裁剪:可以将图片裁剪为特定的尺寸或长宽比。
  3. 水印添加:可以在图片上添加文本或图片形式的水印。
  4. 格式支持:支持多种图像格式,如JPEG、PNG、BMP、GIF等。

Thumbnailator的使用非常直观。你只需要在你的项目中添加Thumbnailator的依赖(比如在Maven或Gradle的构建文件中),然后就可以在代码中调用其提供的方法了。

下面结合项目示例,介绍一下使用Thumbnailator的方法,当然,关于添加水印、裁剪等功能你可以查看其github仓库https://github.com/coobird/thumbnailator

壹、添加依赖

我这里使用的0.4.20版本。

 <!--thumbnailator图片处理-->
 <dependency>
        <groupId>net.coobird</groupId>
        <artifactId>thumbnailator</artifactId>
        <version>0.4.20</version>
</dependency>

贰、创建一个公共类

这里简单介绍一下,getAccuracy是根据原图片大小,判断压缩的比例,压缩比例介于[0,1],比例越小,压缩的越小,当然相应的图片就会越模糊,所以这个比例可以根据实际情况进行调整,尽量保证压缩比例小的情况下,别造成图片失真。

compressPicForScale方法,第一个参数代表源图片字节数组,第二个参数desFileSize代表要压缩到的大小,单位是kbcompressPicForScale方法对输入的图片循环压缩,直至压缩后文件大小<= desFileSize

package net.xiangcaowuyu.common.utils.file;

import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * description: 图片压缩
 *
 * @author: leeframe
 * DateTime: 2024-07-04 11:54
 */
public class PicUtils {

    //以下是常量
    private static final Logger logger = LoggerFactory.getLogger(PicUtils.class);
    private static final Integer ZERO = 0;
    private static final Integer ONE_ZERO_TWO_FOUR = 1024;
    private static final Integer NINE_ZERO_ZERO = 900;
    private static final Integer THREE_TWO_SEVEN_FIVE = 3275;
    private static final Integer TWO_ZERO_FOUR_SEVEN = 2047;
    private static final Double ZERO_EIGHT_FIVE = 0.85;
    private static final Double ZERO_SEVEN_FIVE = 0.75;
    private static final Double ZERO_FOUR_FOUR = 0.44;
    private static final Double ZERO_FOUR = 0.4;

    /**
     * 根据指定大小压缩图片
     *
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小,单位kb
     * @return 压缩质量后的图片字节数组
     */
    public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
        if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR);
        try {
            while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) {
                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("图片原大小={}kb | 压缩后大小={}kb",
                    srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
        } catch (Exception e) {
            logger.error("【图片压缩】msg=图片压缩失败!", e);
        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < NINE_ZERO_ZERO) {
            accuracy = ZERO_EIGHT_FIVE;
        } else if (size < TWO_ZERO_FOUR_SEVEN) {
            accuracy = ZERO_SEVEN_FIVE;
        } else if (size < THREE_TWO_SEVEN_FIVE) {
            accuracy = ZERO_FOUR_FOUR;
        } else {
            accuracy = ZERO_FOUR;
        }
        return accuracy;
    }
}

叁、使用

我这里是借助阿里云OSS,然后下载的网络图片

/**
 * 阿里云文件上传(中保创)
 *
 * @param extension      文件后缀
 * @param ownerDirectory 目录
 */
public String upload(String extension, String ownerDirectory, String url) throws InvalidExtensionException, IOException {
    // 填写网络流地址。
    try (InputStream inputStream = new URL(url).openStream()) {
        // 校验格式、大小等
        String filePath = getFilePath(extension, ownerDirectory);
        byte[] bytesOriginal = IOUtils.toByteArray(inputStream);
        byte[] bytes = PicUtils.compressPicForScale(bytesOriginal, 400);
        ByteArrayInputStream inputStreamCompress = new ByteArrayInputStream(bytes);
        // 上传到阿里云
        ossClient.putObject(aliyunConfig.getBucketName(), filePath, inputStreamCompress);
        //this.aliyunConfig.getUrlPrefix() + filePath 文件路径需要保持数据库
        return aliyunConfig.getUrlPrefix() + filePath;
    }
}
thumbnailator
朗读
赞(0)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

香草物语

本文链接:

https://www.xiangcaowuyu.net/java/using-thumbnailer-to-implement-image-compression.html(转载时请注明本文出处及文章链接)

评论 (0)