The following code uses twelvemonkeys to create a tiff file. The created file gets flushed to disk automatically. But I would like the file to be created in memory only. How to achive this with the 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();
}
To prevent ImageIO
from creating a disk cached ImageOutputStream
, you may invoke the static ImageIO.setUseCache(false)
. The catch here, is that it will disable disk caching for ImageIO
globally, which may not be desirable. In addition, you need to use a ByteArrayOutputStream
or other in-memory structure, to actually store the TIFF image data.
For example:
ImageIO.setUseCache(false); // Typically in a static initializer somewhere
...
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ImageOutputStream output = ImageIO.createImageOutputStream(bytes)) {
... // Write image & meta data
}
Another option which does not affect ImageIO
globally, is to replace the ImageIO.createImageOutputStream(...)
call and just create a new MemoryCacheImageOutputStream(..)
wrapping a ByteArrayOutputStream
to hold the result.
Example:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ImageOutputStream output = new MemoryCacheImageOutputStream(bytes)) {
... // Write image & meta data
}
A third option (which is likely to be slightly more efficient), is to subclass ImageOutputStreamImpl
and implement yourself, using something more fancy, like in-memory ByteChannel
or a ByteBuffer
as backing. The cool thing about this, is obviously that you can use memory-mapped files or off-heap memory. But it will need some more effort to implement.
I'll probably go with the second option, unless profiling or otherwise tells you this doesn't perform well enough for you, then investigate option three.