【问题标题】:DirectBuffer to Speed up ImageIODirectBuffer 加速 ImageIO
【发布时间】:2019-03-14 12:16:15
【问题描述】:

我有很多操作涉及使用第三方库生成 BufferedImage 对象并将其保存到 jpg 文件。有时,一次处理可以节省超过 10,000 个这样的费用。目前我直接使用ImageIO.write(image, "jpg", file),但性能不是很理想。

我想知道是否可以使用直接 ByteBuffer 来加快磁盘写入速度?我正在考虑将 BufferedImage 放入直接的 ByteBuffer 中,最后使用 FileChannel 保存到磁盘。我没有找到这样做的方法。我想知道如何将 BufferedImage 直接放入 ByteBuffer?一些示例代码会很有帮助。

【问题讨论】:

  • 您需要将图像存储为 JPEG 格式吗?如果是这样,您最好的选择可能是使用native bindings for libJPEGTurbo。可以使用 nio 支持的 ImageOutputStreams,但我还没有看到从中获得实质性收益。但是,如果您只想从没有文件格式的内存中转储像素,则使用直接缓冲区可能会起作用。这是一些sample code, using memory mapped BufferedImages
  • 为了提高 ImageIO 的性能,您可能会做的其他事情是禁用磁盘缓存 (ImageIO.setUseCache(false))。但我怀疑如果你仍然写入文件,这会有多大帮助。
  • @haraldK 是的,最后我需要将图像写入 jpg 文件。磁盘缓存有什么帮助?
  • 磁盘缓存没有帮助(对于性能,它确实有助于节省内存)。但它默认启用。我建议你禁用它。
  • 我认为你看错了。内存映射文件不会比内存快。你的BufferedImages 已经在内存中了。如果您进行一些分析,您很可能会发现时间都花在了 JPEG 编码过程中,而不是将结果写入磁盘(假设 SSD 不错)。是的,您可能会使磁盘写入速度更快一些。但真正的收获是切换到更快的编码器。

标签: java nio bufferedimage


【解决方案1】:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public byte[] toByteArray(BufferedImage image) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();            
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
    encoder.encode(image);            
    return baos.toByteArray();
}

来自this 的回答试试这个。应该更快。

【讨论】:

  • 我也设法做到了,但后来我发现byte[]不能保存为jpg文件。
  • 不能保证直接调用 sun.* 包的 Java 程序在所有 Java 兼容平台上都可以工作。事实上,即使在同一平台上的未来版本中,也不能保证这样的程序也能正常工作。 更多信息请参阅Why Developers Should Not Write Programs That Call 'sun' Packages
猜你喜欢
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
相关资源
最近更新 更多