Java BufferedImage JPG压缩而不写入文件

Java BufferedImage JPG compression without writing to file

我看过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 = ???

只需像这样将您的 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);