Scale a BufferedImage the fastest and easiest way

前端 未结 6 591
春和景丽
春和景丽 2020-12-28 15:03

The task: I have some images, I scale them down, and join them to one image. But I have a little problem with the implementation:

The concr

6条回答
  •  抹茶落季
    2020-12-28 15:34

    public static double[] reduceQuality(int quality, int width, int height) {
        if(quality >= 1 && quality <= 100) {
            double[] dims = new double[2];
            dims[0] = width * (quality/100.0);
            dims[1] = height * (quality/100.0);
            return dims;
        } else if(quality > 100) {
            return new double[] { width, height };
        } else {
            return new double[] { 1, 1 };
        }
    }
    
    public static byte[] resizeImage(byte[] data, int width, int height) throws Exception {
        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
        BufferedImage bo = resizeImage(bi, width, height);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(bo, "jpg", bos);
        bos.close();
        return bos.toByteArray();
    }
    
    private static BufferedImage resizeImage(BufferedImage buf, int width, int height) {
        final BufferedImage bufImage = new BufferedImage(width, height, 
                (buf.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB
                : BufferedImage.TYPE_INT_ARGB));
        final Graphics2D g2 = bufImage.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        g2.drawImage(buf, 0, 0, width, height, null);
        g2.dispose();
        return bufImage;
    }
    

    This is taken straight from imgscalr at https://github.com/rkalla/imgscalr/blob/master/src/main/java/org/imgscalr/Scalr.java

    My average time reducing the quality of an image of 8mb with dimensions of 5152x3864 was ~800ms.

    No dependencies. I hate them. Sometimes.

    THIS WILL ONLY WORK WITH jpg IMAGES. As far as I'm concerned.

    Example:

    byte[] of = Files.readAllBytes(Paths.get("/home/user/Pictures/8mbsample.jpg"));
        double[] wh = ImageUtil.reduceQuality(2, 6600, 4950);
    
        long start = System.currentTimeMillis();
        byte[] sof = ImageUtil.resizeImage(of, (int)wh[0], (int)wh[1]);
        long end = System.currentTimeMillis();
    
        if(!Files.exists(Paths.get("/home/user/Pictures/8mbsample_scaled.jpg"))) {
            Files.createFile(Paths.get("/home/user/Pictures/8mbsample_scaled.jpg"), Util.getFullPermissions());
        }
    
        FileOutputStream fos = new FileOutputStream("/home/user/Pictures/8mbsample_scaled.jpg");
        fos.write(sof); fos.close();
    
        System.out.println("Process took: " + (end-start) + "ms");
    

    Output:

    Process took: 783ms
    

提交回复
热议问题