1

I have JPG image files, which I want to load into a BufferedImage and later write the BufferedImage back into a JPG file. Here is what I am currently doing.

Is there a better way not to lose quality and make read/write faster?

Read:

BufferedImage image = ImageIO.read(new File(storagePath + fileName + extension));

Write:

BufferedImage image = // some jpg image         

Iterator iter = ImageIO.getImageWritersByFormatName("JPG");
if (iter.hasNext()) {
    ImageWriter writer = (ImageWriter) iter.next();
    ImageWriteParam iwp = writer.getDefaultWriteParam();
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    iwp.setCompressionQuality(quality);

    File outFile = new File(storagePath + fileName + extension);
    FileImageOutputStream output = new FileImageOutputStream(outFile);
    writer.setOutput(output);
    IIOImage iioImage = new IIOImage(image, null, null);
    writer.write(null, iioImage, iwp);
}
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • I didn't do any benchmarks, but maybe PNG is faster. PNG is always lossless. – Martijn Courteaux Sep 01 '13 at 14:15
  • I know but it takes more memory. And this wasn't my question –  Sep 01 '13 at 14:34
  • Take a look at this: http://stackoverflow.com/questions/7982409/is-jpeg-lossless-when-quality-is-set-to-100 – Martijn Courteaux Sep 01 '13 at 15:41
  • *Writing JPEG is always going to lose quality. Even at 100% quality.* It's a feature of JPEG. If exact reproduction of the source pixels is a requirement, use a different format, like PNG, JPEG2000 (in lossless mode), JPEG-LS (in lossless mode), TIFF or similar. – Harald K Sep 01 '13 at 17:49
  • @haraldK Can you please post an answer with code what I have to do to use JPEG-LS? –  Sep 01 '13 at 17:52
  • @stephan1001 JPEG2000 and JPEG-LS support for ImageIO requires JAI (jai-imageio) with native codecs installed. Apart from that, there should be very little changes to your code. But I never use JAI myself, so I can't guide on the details. – Harald K Sep 01 '13 at 18:06

1 Answers1

1

You can minimize the loss in quality in recompressing JPEG by using the same quantization tables used to correct the original image. It is still possible to get single bit errors from rounding but you can get it pretty close.

The problem is how to get the quantization tables. If your encoded will allow you to specify them, you can pull the values out of the source image. Otherwise, you have to hope that the images were originally encoded using the same encoder.

"Quality Values" are not part of JPEG. They are a method for selecting quantization tables used by some encoder. The LIBJPEG is the most common encoder but there are others out there that do things differently.

PNG encoding is generally slower than JPEG.

user3344003
  • 20,574
  • 3
  • 26
  • 62