Bio-Formats readers and writers are traditionally used to handle image files from disk. However it is also possible to achieve reading and writing of files from in-memory sources. This is handled by mapping the in-memory data to a file location using Location.mapFile().
Location.mapFile(fileName, byteArrayHandle);
This file location is not created on disk but rather maps internally to the in-memory data provided.
In order for Bio-Formats to read a file from memory it must be available in a byte array. For this example an input file is read from disk into a byte array.
// read in entire file
System.out.println("Reading file into memory from disk...");
File inputFile = new File(path);
int fileSize = (int) inputFile.length();
DataInputStream in = new DataInputStream(new FileInputStream(inputFile));
byte[] inBytes = new byte[fileSize];
in.readFully(inBytes);
System.out.println(fileSize + " bytes read.");
This data can now be handled by a Bio-Formats reader. This is achieved by providing a mapping from the in-memory data to a suitable filename which will be used by the reader. The filename used must have the same suffix as the original data type.
// determine input file suffix
String fileName = inputFile.getName();
int dot = fileName.lastIndexOf(".");
String suffix = dot < 0 ? "" : fileName.substring(dot);
// map input id string to input byte array
String inId = "inBytes" + suffix;
Location.mapFile(inId, new ByteArrayHandle(inBytes));
Once the in-memory data has been mapped to a suitable filename the data can be handled by the reader as normal.
// read in entire file
System.out.println("Reading file into memory from disk...");
File inputFile = new File(path);
int fileSize = (int) inputFile.length();
DataInputStream in = new DataInputStream(new FileInputStream(inputFile));
byte[] inBytes = new byte[fileSize];
in.readFully(inBytes);
System.out.println(fileSize + " bytes read.");
To use a writer to output to memory rather than an output file a similar process is required. First a mapping is created between a suitable output filename and the in-memory data.
// map output id string to output byte array
String outId = fileName + ".ome.tif";
ByteArrayHandle outputFile = new ByteArrayHandle();
Location.mapFile(outId, outputFile);
The mapped filename can now be passed to initialize the writer as standard.
// write data to byte array using ImageWriter
System.out.println();
System.out.print("Writing planes to destination in memory: ");
ImageWriter writer = new ImageWriter();
writer.setMetadataRetrieve(omeMeta);
writer.setId(outId);
The data can then be written to memory using the same read and write loop which would normally be used to write a file to disk.
byte[] plane = null;
for (int i=0; i<imageCount; i++) {
if (plane == null) {
// allow reader to allocate a new byte array
plane = reader.openBytes(i);
}
else {
// reuse previously allocated byte array
reader.openBytes(i, plane);
}
writer.saveBytes(i, plane);
System.out.print(".");
}
reader.close();
writer.close();
System.out.println();
byte[] outBytes = outputFile.getBytes();
outputFile.close();
If desired the data written to memory can then be flushed to disk and written to an output file location.
// flush output byte array to disk
System.out.println();
System.out.println("Flushing image data to disk...");
File outFile = new File(fileName + ".ome.tif");
DataOutputStream out = new DataOutputStream(new FileOutputStream(outFile));
out.write(outBytes);
out.close();
See also
ReadWriteInMemory.java - Full source code which is referenced here in part. You will need to have bioformats_package.jar in your Java CLASSPATH in order to compile ReadWriteInMemory.java.