我见过several examples通过写入文件从 Java BufferedImage
对象制作压缩的 JPG 图像,但是是否可以在不写入文件的情况下执行 JPG 压缩?也许通过写入 ByteArrayOutputStream
像 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 = ???
最佳答案
只需将您的 ByteArrayOutputStream
传递给 ImageIO.createImageOutputStream(...)
,如下所示:
// The important part: Create in-memory stream
ByteArrayOutputStream compressed = new ByteArrayOutputStream();
try (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("JPEG").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:默认情况下,ImageIO
在创建 ImageOutputStream
时将使用磁盘缓存。这可能会减慢您的内存流写入速度。要禁用它,请使用 ImageIO.setCache(false)
(全局禁用磁盘缓存)或显式创建 MemoryCacheImageOutputStream
(本地),如下所示:
ImageOutputStream outputStream = new MemoryCacheImageOutputStream(compressed);
关于Java BufferedImage JPG压缩而不写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37713773/