Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
446 views
in Technique[技术] by (71.8m points)

jpeg - Setting jpg compression level with ImageIO in Java

I'm using javax.imageio.ImageIO to save a BufferedImage as a jpeg file. In particular, I created the following Java function:

public static void getScreenShot(BufferedImage capture, Path folder, String filename) {
        try {
            ImageIO.write(capture, "jpeg", new File(folder.toString()+"/"+filename+".jpg"));
        } catch (AWTException | IOException ex) {
            Logger.getLogger(ScreenShotMaker.class.getName()).log(Level.SEVERE, null, ex);
        }
}

Likewise any image manipulation software, I wish to change the compression level of the jpeg file. However, I'm searching for this option that seems to be missing in ImageIO.

Can I set the compression level and how?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A more succinct way is to get the ImageWriter directly from ImageIO:

ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam();
jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpgWriteParam.setCompressionQuality(0.7f);

ImageOutputStream outputStream = createOutputStream(); // For example implementations see below
jpgWriter.setOutput(outputStream);
IIOImage outputImage = new IIOImage(image, null, null);
jpgWriter.write(null, outputImage, jpgWriteParam);
jpgWriter.dispose();

The call to ImageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) is needed in order to explicitly set the compression's level (quality).

In ImageWriteParam.setCompressionQuality() 1.0f is maximum quality, minimum compression, while 0.0f is minimum quality, maximum compression.

ImageWriter.setOutput should be passed an ImageOutputStream. While the method accepts Object, according to documentation it's usually not supported:

Use of a general Object other than an ImageOutputStream is intended for writers that interact directly with an output device or imaging protocol. The set of legal classes is advertised by the writer's service provider's getOutputTypes method; most writers will return a single-element array containing only ImageOutputStream.class to indicate that they accept only an ImageOutputStream.

Most cases should be handled by these two classes:

  • FileImageOutputStream - an implementation of ImageOutputStream that writes its output directly to a File or RandomAccessFile.
  • MemoryCacheImageOutputStream - an implementation of ImageOutputStream that writes its output to a regular OutputStream. Usually used with ByteArrayOutputStream (thanks for the tip, @lmiguelmh!).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...