1.引入依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2.代码
/**
* @Author he
* @Date 2024/2/20 8:41 PM
* @Description
*/
@Slf4j
@Service
public class ImgCompressServiceImpl implements ImgCompressService {
@Autowired
private ImgCompressConfig imgCompressConfig;
@Override
@PFTimed
public byte[] compress(byte[] imgArr, long desFileSize) {
return compressByThumbnails(imgArr, desFileSize, imgCompressConfig.getScale(), imgCompressConfig.getAccuracy(), imgCompressConfig.getOutputFormat(), imgCompressConfig.getLoopMax());
}
/**
* @param srcByteArr 原图片字节数组
* @param desFileSize 目标图片大小
* @param scale 宽高压缩比例
* @param accuracy 图片质量比例
* @param outputFormat 输出图片格式
* @return 目标图片字节数组
*/
public static byte[] compressByThumbnails(byte[] srcByteArr, long desFileSize, double scale, double accuracy, String outputFormat, int loopMax) {
byte[] desByteArr = srcByteArr;
int i = 0;
while (desByteArr.length > desFileSize) {
desByteArr = compressPic(desByteArr, scale, accuracy, outputFormat);
i++;
if (i > loopMax) {
log.warn("compressPicForScale超出循环上限, loop: {}, loopMax: {}", i, loopMax);
throw new BaseApiException(ResponseExceptionEnum.INVALID_ARGUMENT, "desFileSize设置过低,超出压缩限制");
}
}
log.info("compressPicForScale, srcSize: {}, desSize: {}, loop: {}, loopMax: {}", srcByteArr.length, desFileSize, i, loopMax);
return desByteArr;
}
@PFTimed
public static byte[] compressPic(byte[] srcByteArr, double scale, double accuracy, String outputFormat) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(srcByteArr);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
// BufferedImage src = ImageIO.read(inputStream);
// int desWidth = new BigDecimal(src.getWidth()).multiply(new BigDecimal(scale)).intValue();
// int desHeight = new BigDecimal(src.getHeight()).multiply(new BigDecimal(scale)).intValue();
// Thumbnails.of(src)
// .size(desWidth, desHeight)
// .outputQuality(accuracy)
// .outputFormat(outputFormat)
// .toOutputStream(outputStream);
Thumbnails.of(inputStream)
.scale(scale)
.outputQuality(accuracy)
.outputFormat(outputFormat)
.toOutputStream(outputStream);
return outputStream.toByteArray();
} catch (Exception e) {
log.error("图片压缩异常, e: ", e);
throw new BaseApiException(ResponseExceptionEnum.DEPENDENCY_ERROR);
}
}
public static void main(String[] args) throws Exception {
long desFileSize = 50 * 1024L;
String srcPath = "/Users/200k.jpg";
String targetPath = "/Users/50k.jpg";
byte[] srcBytes = FileFormatUtils.image2byteArr(srcPath);
byte[] targetBytes = compressByThumbnails(srcBytes, desFileSize, 0.8, 0.8, "JPG", 10);
File file = new File(targetPath);
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(targetBytes);
bos.close();
fos.close();
// Thumbnails.of("/Users/hebiaobiao1/Desktop/11.jpg")
// .size(1080, 720)
// .outputQuality(0.9)
// .toFile("/Users/hebiaobiao1/Desktop/22.jpg");
}
}
3.工具类
/**
* @Author he
* @Date 2021/10/28 17:46
* @Description
*/
@Slf4j
public class FileFormatUtils {
public static byte[] base642ByteArr(String base64) {
return Base64.decodeBase64(base64);
}
public static byte[] imgUrl2ByteArr(String imgUrl) {
return download(imgUrl);
}
public static String byteArr2Base64(byte[] imgArr) {
return Base64.encodeBase64String(imgArr);
}
public static String imgUrl2Base64(String imgUrl) {
return Base64.encodeBase64String(download(imgUrl));
}
private static byte[] download(String imgUrl) {
URLConnection conn = null;
byte[] imgArr;
try {
conn = URI.create(imgUrl).toURL().openConnection();
conn.setConnectTimeout(2000);
conn.setReadTimeout(5000);
imgArr = IOUtils.toByteArray(conn);
} catch (IOException e) {
log.error("文件下载失败, url: {}, e:{}", imgUrl, e);
throw new RuntimeException("文件下载失败, imgUrl: " + imgUrl, e);
} finally {
if (conn != null) {
close(conn);
}
}
return imgArr;
}
public static byte[] image2byteArr(String path) {
byte[] data = null;
FileImageInputStream input = null;
ByteArrayOutputStream output = null;
try {
input = new FileImageInputStream(new File(path));
output = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int numBytesRead = 0;
while ((numBytesRead = input.read(buf)) != -1) {
output.write(buf, 0, numBytesRead);
}
data = output.toByteArray();
} catch (IOException ex) {
log.error("图片转byteArr异常 msg: {}, ex: {}", ex.getMessage(), ex);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException ex) {
log.error("关闭output异常: msg: {}, ex: {}", ex.getMessage(), ex);
}
}
if (input != null) {
try {
input.close();
} catch (IOException ex) {
log.error("关闭input异常: msg: {}, ex: {}", ex.getMessage(), ex);
}
}
}
return data;
}
public static String image2base64(String path) {
byte[] bytes = image2byteArr(path);
return byteArr2Base64(bytes);
}
}