Java - resize image without losing quality

前端 未结 7 1665
轮回少年
轮回少年 2020-11-29 15:48

I have 10,000 photos that need to be resized so I have a Java program to do that. Unfortunately, the quality of the image is poorly lost and I don\'t have access to the unco

7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-29 16:27

    Below are my own implementation of Progressive Scaling, without using any external library. Hope this help.

    private static BufferedImage progressiveScaling(BufferedImage before, Integer longestSideLength) {
        if (before != null) {
            Integer w = before.getWidth();
            Integer h = before.getHeight();
    
            Double ratio = h > w ? longestSideLength.doubleValue() / h : longestSideLength.doubleValue() / w;
    
            //Multi Step Rescale operation
            //This technique is describen in Chris Campbell’s blog The Perils of Image.getScaledInstance(). As Chris mentions, when downscaling to something less than factor 0.5, you get the best result by doing multiple downscaling with a minimum factor of 0.5 (in other words: each scaling operation should scale to maximum half the size).
            while (ratio < 0.5) {
                BufferedImage tmp = scale(before, 0.5);
                before = tmp;
                w = before.getWidth();
                h = before.getHeight();
                ratio = h > w ? longestSideLength.doubleValue() / h : longestSideLength.doubleValue() / w;
            }
            BufferedImage after = scale(before, ratio);
            return after;
        }
        return null;
    }
    
    private static BufferedImage scale(BufferedImage imageToScale, Double ratio) {
        Integer dWidth = ((Double) (imageToScale.getWidth() * ratio)).intValue();
        Integer dHeight = ((Double) (imageToScale.getHeight() * ratio)).intValue();
        BufferedImage scaledImage = new BufferedImage(dWidth, dHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = scaledImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.drawImage(imageToScale, 0, 0, dWidth, dHeight, null);
        graphics2D.dispose();
        return scaledImage;
    }
    

提交回复
热议问题