需求说明
有一些原始图片,需要将他们的图片尺寸按比例缩小,并使尺寸缩小后的文件大小压缩到指定大小以内,例如海康的设备(考勤机、超脑)上传人脸底图,要求的图片文件大小尺寸在200KB以内。
实现
我是使用的BufferedImage将图片长宽循环执行缩小到一定的比例,然后检测图片文件大小是否达到200KB以内(详见:https://blog.terrynow.com/2022/08/14/java-calculate-buffered-image-estimated-file-size/)
干货代码如下:
public class Test2 {
public static void main(String[] args) throws Exception {
File file = new File("/Users/Terry/Downloads/1518.jpg");
System.out.println("读入原始文件大小: " + (file.length() / 1024.0) + " KB");
if (file.length() < 200 * 1024) {
return;
}
BufferedImage src = ImageIO.read(file); // 读入文件
float scale = 0.8f;//图片长宽缩小为原来的0.8倍
int loop = 0;
while (true) {
byte[] bytes = scaleBufferedImage(src, scale);
System.out.println("文件大小: " + (bytes.length / 1024.0) + " KB");
if (bytes.length < 200 * 1024) {
// 小于200KB了,结束循环,这里简单的保存成了文件,根据实际情况修改
File file1 = new File("/Users/Terry/Downloads/1518_" + scale + ".jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file1);
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileOutputStream.close();
break;
}
if (loop++ > 100) {
throw new Exception("too many loops");
}
src = ImageIO.read(new ByteArrayInputStream(bytes)); // 读入文件,继续循环缩小体积
}
}
// 缩小图片到指定的倍率
public static byte[] scaleBufferedImage(BufferedImage image, float scale) throws Exception {
int newWidth = (int) (image.getWidth() * scale); // 得到图宽
int newHeight = (int) (image.getHeight() * scale); // 得到图长
BufferedImage newBI = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = newBI.getGraphics();
g.drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);
g.dispose();
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
ImageIO.write(newBI, "jpg", tmp);
tmp.close();
return tmp.toByteArray();
}
}
文章评论