一、需要用到的依赖
我用的gradle管理的项目,所有我是这么引用的:
// 处理除png以外的图片 (最新版本在22年10份)
implementation 'net.coobird:thumbnailator:0.4.8'
// 处理png类型的图片 (版本停留在17年,如果使用不了,可以用下面这个)
implementation 'org.jpedal:OpenViewerFX:6.6.14'
如果用maven管理项目的,可以去官网查看对象的依赖包
Maven官网地址:https://mvnrepository.com
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.18</version>
</dependency>
<dependency>
<groupId>org.jpedal</groupId>
<artifactId>OpenViewerFX</artifactId>
<version>6.6.14</version>
</dependency>
二、我们直接上工具类:
2.1、具体需要什么样的,大家可以自行测试一下,如果有更好的办法大家也可能分享一下。
public class ImageUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(ImageUtil.class);
private ImageUtil() {
}
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_SIX = 0.6;
private static final Double ZERO_FOUR_FOUR = 0.44;
private static final Double ZERO_FOUR = 0.4;
/**
* 压缩图片,返回base64字符串 (压缩后图片不丢失精度、不改变大小)
* 接收MultipartFile格式文件;
*
* @param multipartFile MultipartFile
* @return String
*/
public static String compressImageByMultipartFile(MultipartFile multipartFile) {
if (isMultipartFileEmpty(multipartFile)) {
LOGGER.error("error message: 获取图片<url> 失败");
return null;
}
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
PngCompressor.compress(multipartFile.getInputStream(), out);
return Base64.getEncoder().encodeToString(out.toByteArray());
} catch (Exception e) {
LOGGER.error("error message:图片压缩后转<base64>格式、失败,原因:<{}>", String.valueOf(e));
return null;
}
}
/**
* 判断 multipart 文件是否为空
*
* @param file MultipartFile
* @return boolean True-multipart 文件为空 False-multipart 文件不为空
*/
public static boolean isMultipartFileEmpty(MultipartFile file) {
return null == file
|| file.isEmpty();
}
/**
* 根据指定大小压缩图片 (图片会丢失一定的精度、会改变图片的大小、如果不丢失精度、可以优化 Thumbnails.of()参数)
*
* @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("tip message: 图片原大小:<{}>kb | 压缩后大小:<{}>kb",
srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
} catch (Exception e) {
LOGGER.error("error message: <图片压缩>失败、原因:", 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_SIX;
} else if (size < THREE_TWO_SEVEN_FIVE) {
accuracy = ZERO_FOUR_FOUR;
} else {
accuracy = ZERO_FOUR;
}
return accuracy;
}
}