Thumbnailator
是一个用于Java的强大的图片处理库,主要用于创建、缩放和裁剪图片的缩略图。它设计得既简单又功能强大,提供了一系列丰富的特性:
- 尺寸调整:
Thumbnailator
能够根据指定的宽度或高度来调整图片大小。 - 裁剪:可以将图片裁剪为特定的尺寸或长宽比。
- 水印添加:可以在图片上添加文本或图片形式的水印。
- 格式支持:支持多种图像格式,如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
代表要压缩到的大小,单位是kb
,compressPicForScale
方法对输入的图片循环压缩,直至压缩后文件大小<= 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;
}
}
评论 (0)