如何将 ImageOutputStream 的流保存在内存中?
How to keep the stream of ImageOutputStream in memory?
以下代码使用 twelvemonkeys 创建一个 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();
}
要防止 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
并自己实现,使用更奇特的东西,如内存中 ByteChannel
或 ByteBuffer
作为支持。这很酷,显然你可以使用内存映射文件或堆外内存。但它需要更多的努力来实施。
我可能会选择第二个选项,除非分析或以其他方式告诉您这对您来说效果不够好,然后研究选项三。
以下代码使用 twelvemonkeys 创建一个 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();
}
要防止 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
并自己实现,使用更奇特的东西,如内存中 ByteChannel
或 ByteBuffer
作为支持。这很酷,显然你可以使用内存映射文件或堆外内存。但它需要更多的努力来实施。
我可能会选择第二个选项,除非分析或以其他方式告诉您这对您来说效果不够好,然后研究选项三。