README.md

January 26, 2026 · View on GitHub

NOTE (AS OF JAN 2026): This tutorial was written in 2022, and is now quite outdated. It was written before the OME-NGFF specification was published and therefore refers to bioformats2raw v0.5.0 or before which generated a zarr data representation that was a precursor to OME-NGFF/OME-Zarr.

This guide demonstrates how to generate a pyramidal OME-TIFF with Bio-Formats that can be viewed with Avivator. Viv also supports OME-NGFF, but tooling to generate the format remains limited as the specification matures. We will update this tutorial accordingly when a method for generating OME-NGFF is endorsed by the Open Microscopy Environment.

Getting Started

NOTE: If you wish to view an image located on a remote machine accessible via SSH, please see the note at the end of this document.

This tutorial requires Bio-Formats bioformats2raw and raw2ometiff command-line tools. It's easiest to install these tools using conda, but binaries also are available for download on the corresponding github repositories.

$ conda create --name bioformats python=3.8
$ conda activate bioformats
$ conda install -c ome bioformats2raw raw2ometiff

Input data

Bio-Formats is an incredibly valuable toolkit and supports reading over 150 file formats. You can choose one of your own images, but for the purposes of this tutorial, we will use a multiplexed, high-resolution Perkin Elmer (1.95 GB) image made available under CC-BY 4.0 on OME.

$ wget https://downloads.openmicroscopy.org/images/Vectra-QPTIFF/perkinelmer/PKI_scans/LuCa-7color_Scan1.qptiff

Pyramid Generation

First use bioformats2raw to convert the .qptiff format to an intermediate "raw" format. This representation includes the multiscale binary pixel data (Zarr) and associated OME-XML metadata.

$ bioformats2raw LuCa-7color_Scan1.qptiff LuCa-7color_Scan1/

The next step is to convert this "raw" output to an OME-TIFF.

raw2ometiff LuCa-7color_Scan1/ LuCa-7color_Scan.ome.tif

Note: LZW is the default if you do not specify a --compression option (the syntax requires an "=" sign, like --compression=zlib).

You may also use bfconvert (Bioformats >= 6.0.0) to generate an OME-TIFF.

$ bfconvert -tilex 512 -tiley 512 -pyramid-resolutions 6 -pyramid-scale 2  -compression LZW LuCa-7color_Scan1.qptiff LuCa-7color_Scan1.ome.tif

All the above arguments are necessary except for -compression which is optional (default uncompressed). In order for an image to be compatible with Viv:

  • -pyramid-scale must be 2
  • -tilex must equal -tiley (ideally a power of 2)
  • -pyramid-resolutions must be computed using the image dimensions and tile size. For example, for a 4096 x 4096 with tile size of 512, 3 = log2(ceil(4096 / 512)) resolutions should work well. a power of 2), and the -pyramid-resolutions argument should be adjusted to match the size of your image and your choice of tile size. For example, if you have a 4096 x 4096 and tile size of 512, 3 = log2(ceil(4096 / 512)) resolutions should work well. For the LuCa-7color_Scan1.qptiff image, 6 = max(log2(ceil(12480 / 512)), log2(ceil(17280 / 512))) resolutions work best as the image is 12480 x 17280 in size. There is currently no "auto" feature for inferring the number of pyramid resolutions. Without the compression set, i.e -compression LZW, the output image will be uncompressed.

There is a 2GB limit on the total amount of data that may be read into memory for the bfconvert cli tool. Therefore for larger images, please use bioformats2raw + raw2ometiff.

NOTE: Viv currently uses geotiff.js for accessing data from remote TIFFs over HTTP and support the three lossless compression options supported by raw2ometiff - LZW, zlib, and Uncompressed as well as jpeg compression for 8 bit data. Support for JPEG-2000 for >8 bit data is planned. Please open an issue if you would like this more immediately.

Indexed OME-TIFF

The TIFF file format is not designed for the cloud, and therefore certain images are less suitable to be natively read remotely. If your OME-TIFF image contains large non-XY dimensions (e.g. Z=100, T=50), you are likely to experience latencies when switching planes in Avivator due to seeking the file over HTTP. We recommend generating an index (offsets.json) that contains the byte-offsets for each plane to complement OME-TIFF, solving this latency issue and enabling fast interactions.

$ pip install generate-tiff-offsets
$ generate_tiff_offsets --input_file Luca-7color_Scan1.ome.tif

Alternatively you may use our web application for generating the offsets.

⚠️ IMPORTANT ⚠️ Avivator requires the offsets.json file to be adjacent to the OME-TIFF on the server in order to leverage this feature. For example, if an index is generated for the dataset in this tutorial, the following directory structure is correct:

data
├── LuCa-7color_Scan1.offsets.json
└── LuCa-7color_Scan1.ome.tif

This index can be reused by other Viv-based applications and even clients in other languages to improve remote OME-TIFF performance. If using Viv, you must fetch the offsets.json directly in your application code. See our example for help getting started

Viewing in Avivator

⚠️ Warning ⚠️ This section only works in Chrome, Firefox, and Edge (not Safari) due to differences in how browser restrict websites hosted at https:// URLs (Avivator) from issuing requests to http:// (the local data server) as a security measure. The supported browsers allow requests to http:// from https:// under the special case of localhost, whereas Safari prevents all requests to http://. As a workaround, you can start an Avivator client at http://, but we suggest trying a different supported browser. Alternatively, you can drag-and-drop an image (no local server) into the viewer in any browser.

There are a few different ways to view your data in Avivator.

If you have an OME-TIFF saved locally, you may simply drag and drop the file over the canvas or use the "Choose file" button to view your data.

Otherwise Avivator relies on access to data over HTTP, and you can serve data locally using a simple web-server. It's easiest to use http-server to start a web-server locally, which can be installed via npm or Homebrew if using a Mac.

Install http-server

$ npm install --global http-server
# or
$ brew install http-server

Starting a Server

From within this directory, start a local server and open Avivator in your browser.

$ http-server --cors='*' --port 8000 .

This command starts a web-server and makes the content in the current directory readable over HTTP. Once the server is running, open Avivator and paste http://localhost:8000/LuCa-7color_Scan1.ome.tif into the input dialog to view the OME-TIFF generated in this tutorial. For convenience, you can also create a direct link by appending an image_url query parameter:

Troubleshooting: Viv relies on cross-origin requests to retrieve data from servers. The --cors='*' flag is important to ensure that the appropriate Access-Control-Allow-Origin response is sent from your local server. In addition, web servers must allow HTTP range requests to support viewing OME-TIFF images. Range requests are allowed by default by http-server but may need to be enabled explicitly for your production web server.

Viewing an Image via SSH

It is possible to generate the datasets in this tutorial on a remote machine and view them in Avivator via SSH and port forwarding. For example, you can follow this tutorial on a remote machine within SHH, linking your local port 12345 to the remote's local 8000.

$ ssh -L 12345:localhost:8000 <username>@<serverhost> # setup secure shell, link ports
# ... follow tutorial within secure shell, starting http-server on port 8000

Since your local port 12345 is linked to the remote 8000 via SSH, you can now view the remote dataset locally via your localhost:12345 in Avivator: that is, you paste http://avivator.gehlenborglab.org/?image_url=http://localhost:12345/LuCa-7color_Scan1.ome.tif into your browser instead of http://avivator.gehlenborglab.org/?image_url=http://localhost:8000/LuCa-7color_Scan1.ome.tif as is written at the end of the tutorial.

Other Examples

Other sample OME-TIFF data can be downloaded from OME-TIFF sample data provided by OME and viewed with Viv locally (without needing to run Bio-Formats).