如何将ImageOutputStream流保存在内存中?

时间:2016-02-07 13:22:37

标签: tiff javax.imageio twelvemonkeys

以下代码使用十二个monkeys来创建tiff文件。创建的文件会自动刷新到磁盘。但我希望文件只在内存中创建。如何使用ImageOutputStream实现此目的?

try {
  // Create output stream
  ImageOutputStream output = ImageIO.createImageOutputStream(targetFile);

  try {
    writer.setOutput(output);

    ImageWriteParam param = writer.getDefaultWriteParam();
    TIFFImageWriteParam tiffWriteParam = (TIFFImageWriteParam) param;
    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);     

    TIFFImageMetadata metadata = (TIFFImageMetadata) createMetadata(sourceFile);     

    // Set dpi
    String nativeFormat = TIFFMedataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
    // Node nativeTree = metadata.getAsTree(nativeFormat);
    IIOMetadataNode newTree =
        new IIOMetadataNode("com_sun_media_imageio_plugins_tiff_image_1.0");
    IIOMetadataNode ifdNode = new IIOMetadataNode("TIFFIFD");
    newTree.appendChild(ifdNode);
    createTIFFFieldNode(ifdNode, TIFF.TAG_RESOLUTION_UNIT, TIFF.TYPE_SHORT, 2);
    createTIFFFieldNode(ifdNode, TIFF.TAG_X_RESOLUTION, TIFF.TYPE_RATIONAL, new Rational(300));
    createTIFFFieldNode(ifdNode, TIFF.TAG_Y_RESOLUTION, TIFF.TYPE_RATIONAL, new Rational(300));
    metadata.mergeTree(nativeFormat, newTree);

    IIOImage iioimage = new IIOImage(image, null, metadata);
    writer.write(metadata, iioimage, tiffWriteParam);
  } finally {      
    output.close();
  }
} finally {  
  writer.dispose();
}

1 个答案:

答案 0 :(得分:2)

要阻止ImageIO创建磁盘缓存ImageOutputStream,您可以调用静态ImageIO.setUseCache(false)。这里的问题是,它将禁用ImageIO 全局的磁盘缓存,这可能是不可取的。此外,您需要使用ByteArrayOutputStream或其他内存结构来实际存储TIFF图像数据。

例如:

ImageIO.setUseCache(false);  // Typically in a static initializer somewhere

...

ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ImageOutputStream output = ImageIO.createImageOutputStream(bytes)) {
    ... // Write image & meta data
}

另一个不会影响ImageIO全局的选项是替换ImageIO.createImageOutputStream(...)调用,只需创建new MemoryCacheImageOutputStream(..)包裹ByteArrayOutputStream来保存结果。

示例:

ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ImageOutputStream output = new MemoryCacheImageOutputStream(bytes)) {
    ... // Write image & meta data
}

第三个选项(可能稍微提高效率)是子类ImageOutputStreamImpl并使用更加花哨的内容实现自己,例如内存ByteChannelByteBuffer作为支持。很酷的是,你可以使用内存映射文件或堆外内存。但它需要更多的努力来实施。

我可能会选择第二个选项,除非分析或以其他方式告诉您这对您来说效果不佳,然后调查选项三。