tifffile
A comprehensive Python library for reading and writing TIFF, BigTIFF, OME-TIFF, and dozens of proprietary microscopy image formats as NumPy or Zarr arrays.
Repository Health
Technical Analysis
Tifffile is a single-module Python library, maintained by Christoph Gohlke since 2008, for reading and writing TIFF (Tagged Image File Format) files and the many format variants built on top of it. Beyond plain TIFF and BigTIFF, it understands OME-TIFF, GeoTIFF, Adobe DNG, ImageJ hyperstacks, Micro-Manager MMStack and NDTiff, Zeiss LSM, Olympus FluoView/SIS, ScanImage, Aperio SVS, Leica SCN, Hamamatsu NDPI, Philips DP, DICOM-TIFF, ThermoFisher EER, and a dozen more proprietary microscopy and whole-slide-imaging formats, parsing each one’s metadata into a consistent Python API.
Image data moves in and out as NumPy arrays via the imread/imwrite convenience functions, or as Zarr arrays and groups for memory-mapped, chunked, or pyramidal access to files too large to load at once. Compression and prediction schemes (LZW, JPEG, JPEG 2000/XR/XL, Zstd, LERC, WebP, PNG, packed integers, and more) are delegated to the companion imagecodecs library. The package is a foundational dependency in the scientific Python bioimaging stack, underpinning tools like scikit-image, napari, and OME’s own tooling for microscopy file I/O.
What You Get
- imread/imwrite convenience functions for one-line array-to-TIFF and TIFF-to-array conversion
- A TiffFile class for detailed page-by-page and tag-by-tag inspection of a file’s IFD structure
- Zarr-backed array and group access for memory-mapped, chunked, or pyramidal reads of huge files
- Support for parsing metadata from over a dozen proprietary microscopy/whole-slide formats (LSM, NDPI, SVS, SCN, QPTIFF, etc.)
- Command-line tools (tifffile, tiffcomment, tiff2fsspec, lsm2bin) for inspecting and patching TIFF files without writing code
Common Use Cases
- Loading multi-dimensional microscopy image stacks (Z/T/C hyperstacks) into NumPy for analysis in scikit-image or napari
- Streaming pyramidal whole-slide images (Aperio SVS, Philips DP, Hamamatsu NDPI) as Zarr arrays without loading the full file into memory
- Writing scientific NumPy arrays to OME-TIFF or BigTIFF for interoperability with Fiji/ImageJ and other bioimaging tools
- Patching or inspecting individual TIFF tags (e.g., resolution, description) in existing files
Under The Hood
Architecture The whole functional surface lives in a single ~28,000-line module (tifffile/tifffile.py) organized as a flat but internally layered set of classes: TiffFile is the top-level file handle that lazily parses the IFD chain into TiffPages/TiffFrames, TiffPageSeries groups pages into logical image series (handling ome/imagej/shaped/stk/lsm “kinds”), and TiffWriter mirrors that on the write side; array access is decoupled through a separate zarr.py module (TiffStore/ZarrTiffStore, ZarrFileSequenceStore) that wraps the same page/IFD objects behind the Zarr store protocol, and _imagecodecs.py isolates the optional compression backend so codec support degrades gracefully when imagecodecs isn’t installed. There’s no dependency-injection framework — configuration flows through constructor/function keyword arguments (photometric, planarconfig, kind, etc.) — but the strict separation between “parse structure” (TiffFile/TiffPage), “expose as array” (TiffPageSeries/Zarr stores), and “encode/decode bytes” (_imagecodecs) means the core tag/IFD model can absorb a new proprietary format by adding a new “kind” branch without touching the read/write byte-level machinery.
Tech Stack Pure Python 3.12+, with a single hard dependency (numpy>=2.1); everything else — imagecodecs for non-baseline compression, lxml for XML metadata validation, zarr/fsspec/kerchunk for chunked or remote array access, xarray for labeled-array export, matplotlib for the built-in interactive viewer, dask/pytest for testing — is declared as optional extras in setup.py’s extras_require (codecs/xml/zarr/plot/all/test groups). Packaging is plain setuptools (setup.py plus a minimal pyproject.toml build-system block, no Poetry/Hatch), the module ships a py.typed marker for downstream type checkers, and console_scripts entry points (tifffile, tiffcomment, tiff2fsspec, lsm2bin) are registered directly in setup.py rather than through a separate CLI framework.
Code Quality
The test suite is a single large pytest file exercising hundreds of tests against real sample files for the many supported vendor formats rather than only synthetic fixtures, with a conftest.py that prints dependency versions in the report header and supports a SKIP_CODECS environment variable to test the fallback path when imagecodecs is absent. The source is extensively documented with reST docstrings and doctested examples in the module header, uses from __future__ import annotations with type hints throughout, and its many explicit raise sites show intentional validation with specific error messages rather than silent fallbacks. No CI configuration is present in the repository itself, and there’s no linter/formatter config beyond black/isort settings in pyproject.toml, suggesting releases are validated locally by the maintainer rather than through automated in-repo checks.
API Design The public API is deliberately narrow at the top (three names — TiffFile, imread, imwrite — cover the common cases) while still surfacing the full page/tag/series object model for anyone who needs it, so a newcomer can be productive from the README’s doctested one-liners while power users get direct access to IFD tags and Zarr stores. Keyword arguments like photometric, planarconfig, and kind read as intent rather than raw format bits, and consistent naming (TiffFile/TiffPage/TiffPageSeries/TiffWriter) makes the object graph predictable, though the sheer size of the single-module surface area means discoverability leans heavily on docstrings and the README’s example gallery rather than a curated docs site.