Java循环缩小图片尺寸至指定的文件大小以内的实现

2022-08-15 772点热度 0人点赞 0条评论

需求说明

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

}

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论