需求说明
有一些原始图片,需要将他们的图片尺寸按比例缩小,并使尺寸缩小后的文件大小压缩到指定大小以内,例如海康的设备(考勤机、超脑)上传人脸底图,要求的图片文件大小尺寸在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(); } }
文章评论