1
votes

I want to compress(reduce) image size using Java. We can upload images in jpg/jpeg/png formats. The general format of images is PNG. So, after image uploaded to the server, we need to compress(reduce file size) and convert it to PNG.

I have the next code for the compress image:

    BufferedImage bufferedImage = ImageIO.read(inputStream);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    switch (imageType) {
        case PNG:
        case JPG:
            // need Java 9+ for PNG writer support
            ImageWriter writer = ImageIO.getImageWritersByFormatName(imageType.getExtension()).next();
            ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
            writer.setOutput(ios);

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

            writer.write(null, new IIOImage(bufferedImage, null, null), param);
            writer.dispose();
            return new ByteArrayInputStream(outputStream.toByteArray());
        default:
            log.warn("Image type unknown");
            return null;
    }

The problem is - after processing the image, I got the result - file size increased instead of reducing. The original image has a lower size than compressed. Any suggestions on how to solve this issue?

2
What kind of images are you dealing with? PNG may not be the best choice for every kind of image (e.g. photos). - Michael
@Michael on server all images saved in PNG. But the user can upload jpg/jpeg and png. It is images like user profile images, user post images, albums and etc. - Volodymyr Zavada
Does the compression need to be lossless? If so, maybe you can use WebP instead of PNG? - Michael

2 Answers

1
votes

Unfortunately the lossy JPEG compression compresses far better than the lossless PNG compression. You could restrict width and height of the image and scale proportionally.

So I would switch to JPEG and restrict the size.

2
votes

As a solution for this problem I can recommend the API of TinyPNG.
You can use it for compressing as well as resizing the image.

It works for both .jpeg and .png.

Documentation: tinypng.com/developers/reference/java