Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to compress a PNG image using Java

Hi I would like to know if there is any way in Java to reduce the size of an image (use any kind of compression) that was loaded as a BufferedImage and is going to be saved as an PNG.

Maybe some sort of png imagewriteparam? I didnt find anything helpful so im stuck.

heres a sample how the image is loaded and saved

public static BufferedImage load(String imageUrl) {         
    Image image = new ImageIcon(imageUrl).getImage();
    bufferedImage = new BufferedImage(image.getWidth(null),
                                                    image.getHeight(null),
                                                    BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2D = bufferedImage.createGraphics();
    g2D.drawImage(image, 0, 0, null);
    return bufferedImage;
}

public static void storeImageAsPng(BufferedImage image, String imageUrl) throws IOException {
    ImageIO.write(image, "png", new File(imageUrl));
}
like image 304
ubernoob Avatar asked Apr 27 '10 12:04

ubernoob


People also ask

How do I reduce the size of a PNG?

One of the most basic ways to cut down on a PNG's file size is to limit the number of colors that the image has. PNGs can be saved as Grayscale, Truecolor, Indexed-color, Grayscale with alpha, and Truecolor with alpha. Being saved with alpha means that the PNG also has transparency.

Does Java support PNG?

Java 2D supports loading these external image formats into its BufferedImage format using its Image I/O API which is in the javax. imageio package. Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP.

How do I reduce the size of a PNG in Python?

A built-in parameter for saving JPEGs and PNGs is optimize . The optimize flag will do an extra pass on the image to find a way to reduce its size as much as possible. 1.9kb might not seem like much, but over hundreds/thousands of pictures, it can add up.


1 Answers

By calling ImageIO.write you use the default compression quality for pngs. You can choose an explicit compression mode which reduces file size a lot.

String inputPath = "a.png";
String outputPath = "b.png";

BufferedImage image;
IIOMetadata metadata;

try (ImageInputStream in = ImageIO.createImageInputStream(Files.newInputStream(Paths.get(inputPath)))) {
    ImageReader reader = ImageIO.getImageReadersByFormatName("png").next();
    reader.setInput(in, true, false);
    image = reader.read(0);
    metadata = reader.getImageMetadata(0);
    reader.dispose();
}

try (ImageOutputStream out = ImageIO.createImageOutputStream(Files.newOutputStream(Paths.get(outputPath)))) {
    ImageTypeSpecifier type = ImageTypeSpecifier.createFromRenderedImage(image);
    ImageWriter writer = ImageIO.getImageWriters(type, "png").next();

    ImageWriteParam param = writer.getDefaultWriteParam();
    if (param.canWriteCompressed()) {
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(0.0f);
    }

    writer.setOutput(out);
    writer.write(null, new IIOImage(image, null, metadata), param);
    writer.dispose();
}
like image 112
Kristof Neirynck Avatar answered Sep 19 '22 05:09

Kristof Neirynck