Java BufferedImage JPG压缩而不写入文件

标签 java image jpeg bufferedimage

我见过several examples通过写入文件从 Java BufferedImage 对象制作压缩的 JPG 图像,但是是否可以在不写入文件的情况下执行 JPG 压缩?也许通过写入 ByteArrayOutputStreamthis

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/

相关文章:

java - 如何使用 Guava 谓词获取数组列表中的重复元素

java - 将平面 JSON 对象分配给多个类

ios - 当 iOS 缩小图像时,它会剪辑/像素化它吗?

c# - 是否可以从控件创建 JPG?

php - 使用ghostscript输出文件目录

c# - 如何使用无损方法压缩和解压缩 JPEG?

java - Java 中的可过期 Kerberos 票证

java - 如何在 netbeans 7.4 中删除 hibernate 中的警告

java - Wicket 口动态图像 URL

html - 拉伸(stretch)图像作为背景