Standalone multi-channel OME-TIFF viewer with a built-in web UI.
Point it at a file or a folder and open your browser.
- What it is
- Supported formats
- Installation
- Quick start
- Command-line reference
- Environment variables
- Configuration file
- Filename conventions
- Programmatic use
- Troubleshooting
- Development
- Docker migration
- License
- Acknowledgements
TissueViewer is a zero-config viewer for high-resolution multi-channel microscopy images. It serves deep-zoom tiles over HTTP and ships with a pre-built OpenSeadragon front-end that lets you colourise channels, adjust gains and windowing, and save per-slide settings.
- OME-TIFF (
.ome.tif,.ome.tiff) — any bit depth, any number of channels, with or without a built-in pyramid.
Support for additional formats (plain TIFF, OME-Zarr) is planned as
pluggable handlers; see src/tissueviewer/formats/ for the registry.
pip install tissueviewerOr from a source checkout:
git clone https://github.com/davidvi/tissueviewer.git
cd tissueviewer
pip install .Requires Python 3.10 or later. On macOS / Linux / Windows.
Open a single file:
tissueviewer /path/to/slide.ome.tiffBrowse a folder of slides (root folder becomes the public location):
tissueviewer /path/to/slidesBrowse a nested tree of folders:
tissueviewer /path/to/slides --recursive --openUse a config file:
tissueviewer --config config.yamlCheck every file in a directory can be opened, then exit:
tissueviewer /path/to/slides --validateusage: tissueviewer [TARGET] [options]
positional:
TARGET Path to an .ome.tif(f) file or a directory of them.
options:
-r, --recursive Include nested subdirectories.
-c, --config FILE YAML configuration file.
-p, --port N Listen port (default 8000).
-H, --host HOST Bind address (default 127.0.0.1).
-o, --open Open the default web browser after start.
-w, --watch Rescan TARGET on filesystem changes.
--validate Verify every OME-TIFF, then exit.
--no-save Disable writing .sample.json sidecars.
--log-level LEVEL DEBUG | INFO | WARNING | ERROR (default INFO).
-V, --version Show version and exit.
-h, --help Show help and exit.
TARGET is optional if either --config is given or TV_SLIDE_DIR is set.
Kept for backward compatibility with the Docker deployment. CLI and config values take precedence.
| Variable | Effect |
|---|---|
TV_SLIDE_DIR |
Default data directory (equivalent to positional TARGET). |
TV_HOST |
Default bind address. |
TV_PORT |
Default listen port. |
TV_SAVE |
false/0/no disables sample.json writes. |
TV_LOG_LEVEL |
Default log level. |
# config.yaml
data_dir: /srv/tissue-viewer/slides
recursive: true
host: 0.0.0.0
port: 8000
save_enabled: false
log_level: INFO
colors:
- red
- green
- bluetissueviewer --config config.yamlPrecedence (highest wins): CLI flags → environment variables → YAML → built-in defaults.
All recognized slide files end in .ome.tif or .ome.tiff (case-insensitive).
For a slide named patient42.ome.tiff, two sidecar files may appear next
to it:
| File | Who writes it | Purpose |
|---|---|---|
patient42.sample.json |
the web UI | Per-slide channel colours / gains / annotations. |
patient42.metadata.json |
TissueViewer itself | Cache of OME-XML metadata; regenerated on mtime. |
Delete them freely to reset.
The web UI groups slides into locations. The mapping:
- Single-file mode → the file lives under the
publiclocation. - Directory mode (no
--recursive) → files at the root →public; every immediate subdirectory → its own location named after the subdirectory. - Directory mode with
--recursive→ files at the root still go topublic; files in nested subdirectories are grouped under a slash-joined location path like2024/batch_A.
create_app builds a regular FastAPI instance, suitable for any ASGI
server (uvicorn, hypercorn, daphne).
from tissueviewer import Config, create_app
app = create_app(Config(data_dir="/srv/slides", recursive=True))uvicorn my_module:app --host 0.0.0.0 --port 8000ModuleNotFoundError: imagecodecs— installimagecodecsor reinstalltissueviewer; many OME-TIFFs use LZW/JPEG/Zstd compression.- Port already in use —
tissueviewer --port 8001. - Blank tiles / wrong colours — delete the slide's
.sample.jsonto reset settings, then reload. - Apple Silicon wheels —
imagecodecsandopencv-python-headlessship arm64 wheels; no local build required. - Zarr 2 vs 3 — both are supported. The pin is
zarr>=2.15,<4. - OpenCV GUI warning —
tissueviewerdepends onopencv-python-headless; a warning aboutcv2.imshownot being available is normal and harmless.
See CONTRIBUTING.md for local setup, how to rebuild the Vue UI, and how to cut a release.
TissueViewer used to ship as a Docker image with a Java-based
bioformats2raw conversion pipeline. That mode is gone in 0.2; see
MIGRATION.md for guidance.
Creative Commons Attribution-NonCommercial 4.0 International — see LICENSE.md.
TissueViewer uses OpenSeadragon for high-performance tiled image visualisation.