# Exporting files using Bio-Formats

This guide pertains to version 4.2 and later.

## Basic conversion

The first thing we need to do is set up a reader:

    // create a reader that will automatically handle any supported format
    IFormatReader reader = new ImageReader();
    // tell the reader where to store the metadata from the dataset
    MetadataStore metadata;

    try {
      ServiceFactory factory = new ServiceFactory();
      OMEXMLService service = factory.getInstance(OMEXMLService.class);
      metadata = service.createOMEXMLMetadata();
    }
    catch (DependencyException exc) {
      throw new FormatException("Could not create OME-XML store.", exc);
    }
    catch (ServiceException exc) {
      throw new FormatException("Could not create OME-XML store.", exc);
    }

    reader.setMetadataStore(metadata);
    // initialize the dataset
    reader.setId("/path/to/file");

Now, we set up our writer:

    // create a writer that will automatically handle any supported output format
    IFormatWriter writer = new ImageWriter();
    // give the writer a MetadataRetrieve object, which encapsulates all of the
    // dimension information for the dataset (among many other things)
    OMEXMLService service = factory.getInstance(OMEXMLService.class);
    writer.setMetadataRetrieve(service.asRetrieve(reader.getMetadataStore()));
    // initialize the writer
    writer.setId("/path/to/output/file");

Note that the extension of the file name passed to ‘writer.setId(…)’ determines the file format of the exported file.

Now that everything is set up, we can start writing planes:

    for (int series=0; series<reader.getSeriesCount(); series++) {
      reader.setSeries(series);
      writer.setSeries(series);

      for (int image=0; image<reader.getImageCount(); image++) {
        writer.saveBytes(image, reader.openBytes(image));
      }
    }

Finally, make sure to close both the reader and the writer. Failure to do so can cause:

- file handle leaks

- memory leaks

- truncated output files

Fortunately, closing the files is very easy:

    reader.close();
    writer.close();

## Converting to multiple files

The recommended method of converting to multiple files is to use a single IFormatWriter, like so:

    // you should have set up a reader as in the first example
    ImageWriter writer = new ImageWriter();
    OMEXMLService service = factory.getInstance(OMEXMLService.class);
    writer.setMetadataRetrieve(service.asRetrieve(reader.getMetadataStore()));
    // replace this with your own filename definitions
    // in this example, we're going to write half of the planes to one file
    // and half of the planes to another file
    String[] outputFiles =
      new String[] {"/path/to/file/1.tiff", "/path/to/file/2.tiff"};
    writer.setId(outputFiles[0]);

    int planesPerFile = reader.getImageCount() / outputFiles.length;
    for (int file=0; file<outputFiles.length; file++) {
      writer.changeOutputFile(outputFiles[file]);
      for (int image=0; image<planesPerFile; image++) {
        int index = file * planesPerFile + image;
        writer.saveBytes(image, reader.openBytes(index));
      }
    }

    reader.close();
    writer.close();

The advantage here is that the relationship between the files is preserved when converting to formats that support multi-file datasets internally (namely OME-TIFF). If you are only converting to graphics formats (e.g. JPEG, AVI, MOV), then you could also use a separate IFormatWriter for each file, like this:

    OMEXMLService service = factory.getInstance(OMEXMLService.class);
    // again, you should have set up a reader already
    String[] outputFiles = new String[] {"/path/to/file/1.avi", "/path/to/file/2.avi"};
    int planesPerFile = reader.getImageCount() / outputFiles.length;
    for (int file=0; file<outputFiles.length; file++) {
      ImageWriter writer = new ImageWriter();
      writer.setMetadataRetrieve(service.asRetrieve(reader.getMetadataStore()));
      writer.setId(outputFiles[file]);
      for (int image=0; image<planesPerFile; image++) {
        int index = file * planesPerFile + image;
        writer.saveBytes(image, reader.openBytes(index));
      }
      writer.close();
    }