java实现图片的压缩且保留图片尺寸不变
以下压缩图片的方式,可以指定压缩的大小,比如指定压缩到512kb以下,并且能保留原始图片尺寸大小不变,改变的是图片的质量、清晰度。
·
说明:以下压缩图片的方式,可以指定压缩的大小,比如指定压缩到 512kb 以下,并且能保留原始图片尺寸大小不变,改变的是图片的质量、清晰度
引入的依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.17</version>
</dependency>
实现的工具类
package com.yuhuofei.utils;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import java.io.*;
import java.util.Objects;
/**
* @Description 保留图片尺寸大小,通过压缩图片质量的方式压缩图片大小
* @ClassName PictureUtils
* @Author yuhuofei
* @Date 2022/7/29 22:42
* @Version 1.0
*/
@Slf4j
public class PictureUtils {
/**
* 利用递归方式,不断检索多层文件夹中的图片,并压缩
*
* @param sourceFolderPath 文件夹路径
*/
public static void checkFolder(String sourceFolderPath) {
File sourceFolder = new File(sourceFolderPath);
String[] sourceFilePathList = sourceFolder.list();
String tempFileString;
if (null != sourceFilePathList) {
for (String filePath : sourceFilePathList) {
tempFileString = sourceFolderPath + "/" + filePath;
File currentFile = new File(tempFileString);
//递归检索
if (currentFile.isDirectory()) {
log.info("当前处理文件夹:{}", tempFileString);
checkFolder(tempFileString);
}
//如果是.jpg图片或者.JPG图片,调用压缩方法压缩处理
if (currentFile.isFile() && (filePath.contains(".jpg") || filePath.contains(".JPG"))) {
compressPicForScale(Objects.requireNonNull(fileSwitchToByte(currentFile)), 512, tempFileString);
}
}
}
}
/**
* 根据指定大小压缩图片
*
* @param imageBytes 原图片字节数组大小
* @param targetFileSize 要压缩的大小
* @param picturePath 图片绝对路径
*/
public static void compressPicForScale(byte[] imageBytes, long targetFileSize, String picturePath) {
long srcSize = imageBytes.length;
if (srcSize > targetFileSize * 1024) {
log.info("当前压缩的图片是:{}", picturePath);
File file = new File(picturePath);
long tempSize = srcSize;
double accuracy = getAccuracy(srcSize / 1024);
try {
while (tempSize > targetFileSize * 1024) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
FileOutputStream fileOutputStream = new FileOutputStream(file);
Thumbnails.of(inputStream)
.scale(accuracy)
.outputQuality(accuracy)
.toOutputStream(fileOutputStream);
tempSize = file.length();
}
} catch (Exception e) {
log.error("====压缩图片失败====", e);
}
}
}
/**
* 校准压缩精度
*
* @param size 源图片大小
* @return 图片压缩质量比
*/
private static double getAccuracy(long size) {
double accuracy;
if (size < 900) {
accuracy = 0.85;
} else if (size < 2047) {
accuracy = 0.6;
} else if (size < 3275) {
accuracy = 0.44;
} else {
accuracy = 0.4;
}
return accuracy;
}
/**
* 将文件对象转换为字节数组
*
* @param file 文件对象
* @return byte[]
*/
public static byte[] fileSwitchToByte(File file) {
FileInputStream fileInputStream = null;
ByteArrayOutputStream bs = null;
try {
fileInputStream = new FileInputStream(file);
bs = new ByteArrayOutputStream();
byte[] b = new byte[2048];
int len;
while ((len = fileInputStream.read(b)) != -1) {
bs.write(b, 0, len);
}
return bs.toByteArray();
} catch (IOException e) {
log.error("字节数组转换失败" + e);
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (bs != null) {
bs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//测试方式
public static void main(String[] args) {
log.info("====开始检索文件夹中的图片,并压缩====");
String folderPath = "C:/Users/yuhuofei/Desktop/data/材料";
checkFolder(folderPath);
log.info("====文件夹中的图片,压缩处理完成====");
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)