user3011902
user3011902

Reputation:

Java - Compressing an Image without Quality Loss

I have a jpeg Image that is 2.1mb in size. I am attempting to compress the Image data as much as possible. Possibly below 1mb. Currently I have done some research on the subject and I have written some code to attempt to compress the data. I have stumbled upon this Answer:

https://stackoverflow.com/a/4535883/3011902

Based on this I have converted an Image file to a byte array, and then converted the byte array to its binary equivalent. Then I use run length encoding on the binary data. This makes the size larger however.

I have tried to convert the file to a png. But that increased the file size dramatically; 9mb.

So what is the best way in Java to compress and Image files size without quality loss?

Upvotes: 4

Views: 5427

Answers (1)

user2864740
user2864740

Reputation: 61875

JPEG is a lossy image compression of the original source image. When the JPEG-compressed image is loaded it has the same size (W x H) as the original and data (BPP) per pixel - albeit the information is already a corruption/quantization of the original information. This means that the same amount of data represents less of the original information.

Trying to apply a lossless compression - be it PNG or a manual RLE - to the restored image1 will result in a larger file size because the new compression will faithfully preserve the artifacts and existing information loss 4. Since JPEG can introduce extra noise the restored data may even make applying lossless compression techniques less efficient.

To get the best compression/quality trade-off start with the original raw image information (RAW, BMP, TIFF); and apply an image compression format based on need. This may be choosing a lossless format (like PNG, WEBP) or it may be choosing a lossy format like JPEG (of which there are several variants) with different compression settings. If the image is already a lossy JPEG the best solution (without reducing the image/data size) may simply be to leave it alone.

Different compression algorithms will obtain different results - including apparent loss of quality for lossy formats - based upon the content of the image. For instance, a simple RLE2 compression will work well on images of many large same-color regions but JPEG will work much better on photos3.


1 If applying a general compression (eg. DEFLATE, bzip2) over the byte stream, which already represents well compressed data, there might be a few percentage of space saved. However since the image is not first restored in this case there is not the same inflation as reapplying a lossless image compression to the loaded 'full data' image.

2 Among its other tricks PNG applies several RLE-style algorithms and will probably be as good or better than a manual implementation. PNG is especially well suited to icons that are normally relatively simple (compared to photos) and must be pixel-perfect when restored.

3 Part of the reason JPEG can compress photos well is that it purposefully throws out information of less importance to human vision and applies 'good enough for human perception' approximations to compressed blocks.

4 Even re-saving the JPEG image (after modifications) can result in further image degradation; there are some papers on 'JPEG transcoding' which may be an interesting read.

Upvotes: 4

Related Questions