Java BufferedImage JPG compression without writing to file

♀尐吖头ヾ 提交于 2019-12-31 03:33:10

问题


I've seen several examples of making compressed JPG images from Java BufferedImage objects by writing to file, but is it possible to perform JPG compression without writing to file? Perhaps by writing to a ByteArrayOutputStream like this?

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

ImageOutputStream outputStream = createOutputStream();
jpgWriter.setOutput(outputStream);
IIOImage outputImage = new IIOImage(image, null, null);

// in this example, the JPG is written to file...
// jpgWriter.write(null, outputImage, jpgWriteParam);
// jpgWriter.dispose();

// ...but I want to compress without saving, such as
ByteArrayOutputStream compressed = ???

回答1:


Just pass your ByteArrayOutputStream to ImageIO.createImageOutputStream(...) like this:

// The important part: Create in-memory stream
ByteArrayOutputStream compressed = new ByteArrayOutputStream();
ImageOutputStream outputStream = ImageIO.createImageOutputStream(compressed);

// NOTE: The rest of the code is just a cleaned up version of your code

// Obtain writer for JPEG format
ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();

// Configure JPEG compression: 70% quality
ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam();
jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpgWriteParam.setCompressionQuality(0.7f);

// Set your in-memory stream as the output
jpgWriter.setOutput(outputStream);

// Write image as JPEG w/configured settings to the in-memory stream
// (the IIOImage is just an aggregator object, allowing you to associate
// thumbnails and metadata to the image, it "does" nothing)
jpgWriter.write(null, new IIOImage(image, null, null), jpgWriteParam);

// Dispose the writer to free resources
jpgWriter.dispose();

// Get data for further processing...
byte[] jpegData = compressed.toByteArray();

PS: By default, ImageIO will use disk caching when creating your ImageOutputStream. This may slow down your in-memory stream writing. To disable it, use ImageIO.setCache(false) (disables disk caching globally) or explicitly create an MemoryCacheImageOutputStream (local), like this:

ImageOutputStream outputStream = new MemoryCacheImageOutputStream(compressed);


来源:https://stackoverflow.com/questions/37713773/java-bufferedimage-jpg-compression-without-writing-to-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!