JPEG Output (with quality control)

This is applicable to Java apps in general and is not specific to Eclipse. The ImageIO class supports loading and saving JPEG files, but setting the quality level for the saved JPEG was not obviously available through ImageIO, thus the following can be used to save a JPEG with a quality level setting.

import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Locale;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;

/**
* Utility methods that allow you to output JPEG images with the opportunity to
* specify the quality setting for the compression.
*
*/

public class JPEGOutputUtil {
    private JPEGOutputUtil() {}


    /**
    * Write the image to the stream as a JPEG with highest quality / low compression.
    * @param os
    * @param image
    * @return
    */

    public static boolean writeJPEGImageStream(OutputStream os, RenderedImage image) {
        try {
            compressJpegStream(os, image, 1.0f);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
    * @param outFile
    * @param image
    * @param compressionQuality
    * @throws IOException
    */

    public static void compressJpegFile(File outFile, RenderedImage image, float compressionQuality)
            throws IOException {
        OutputStream outStream = new FileOutputStream(outFile);
        compressJpegStream(outStream, image, compressionQuality);
    }

    /**
    * @param outStream
    * @param image
    * @param compressionQuality 0.0 for low quality / high compression to 1.0 for high quality / low compression
    * @throws IOException
    */

    public static void compressJpegStream(OutputStream outStream, RenderedImage image, float compressionQuality)
            throws IOException {
        // Find a jpeg writer
        ImageWriter writer = null;
        Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");
        if (iter.hasNext()) {
            writer = iter.next();
        }

        // Set the compression quality
        ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault()) {
            public void setCompressionQuality(float quality) {
                if (quality < 0.0F || quality > 1.0F) {
                    throw new IllegalArgumentException("Quality out-of-bounds!");
                }
                this.compressionQuality = quality;
            }
        };
        iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
        iwparam.setCompressionQuality(compressionQuality);

        // Prepare output file
        ImageOutputStream ios = ImageIO.createImageOutputStream(outStream);
        writer.setOutput(ios);

        // Write the image
        writer.write(null, new IIOImage(image, null, null), iwparam);

        // Cleanup
        ios.flush();
        writer.dispose();
        ios.close();
    }

}