Developer guide

How to Read SVS Files in Python

An Aperio SVS file is a tiled, pyramidal TIFF: the full-resolution scan plus smaller copies of it, a thumbnail, and usually label and macro photos. In Python, read it with openslide-python when you want regions, tiles and slide properties, or with tifffile when you want NumPy arrays. Every example below was run on real SVS slides before we published it.

Tested on JPEG and JPEG 2000 SVSWindows, macOS, LinuxCopy-paste examples

Install the libraries

Pick one library or install both. openslide-bin ships the OpenSlide C library as a wheel for Windows, macOS and Linux, so there is nothing else to install. imagecodecs lets tifffile decode the JPEG 2000 compression many Aperio scanners use.

# OpenSlide
pip install openslide-python openslide-bin

# tifffile (NumPy arrays)
pip install tifffile imagecodecs zarr

Tested on 8 October 2026 with Python 3.13 on Windows 11: openslide-python 1.4.6, openslide-bin 4.0.1.2, tifffile 2026.9.20, imagecodecs 2026.8.16, zarr 3.4.1 and Pillow 12.3.0. The test slides were CMU-1-JP2K-33005.svs and CMU-1-Small-Region.svs from the OpenSlide test data, plus a 20× kidney slide with JPEG tiles.

Read an SVS file with OpenSlide

OpenSlide opens the slide lazily, so this is fast even for multi-gigabyte files. Only the pixels you ask for are decoded.

import openslide

slide = openslide.OpenSlide("slide.svs")

print(slide.dimensions)          # full-resolution (width, height)
print(slide.level_count)         # number of pyramid levels
print(slide.level_dimensions)    # (width, height) of every level
print(slide.level_downsamples)   # 1.0, 4.0, 16.0, ...

mpp_x = slide.properties.get(openslide.PROPERTY_NAME_MPP_X)
print("microns per pixel:", mpp_x)

# A 1024 x 1024 region at full resolution; (x, y) are level-0 coordinates
region = slide.read_region((0, 0), 0, (1024, 1024)).convert("RGB")
region.save("region.png")

# A thumbnail that fits in 1024 x 1024
slide.get_thumbnail((1024, 1024)).save("thumbnail.png")

# The label and macro photos, when the scanner saved them
print(list(slide.associated_images))
slide.close()

Output for CMU-1-JP2K-33005.svs

(46000, 32893)
3
((46000, 32893), (11500, 8223), (2875, 2055))
(1.0, 4.000060805058981, 16.003163017031632)
microns per pixel: 0.499
['label', 'macro', 'thumbnail']
  • Sizes are (width, height). NumPy arrays are (rows, columns), so numpy.asarray(region) has the shape (height, width, 3).
  • read_region returns RGBA. Pixels outside the scanned area are transparent; .convert("RGB") drops the alpha channel.
  • A white region is usually glass, not a bug. The top-left corner of most slides is empty background. Find the tissue on the thumbnail first, then scale its position up by the level-0 size.

Read an SVS file into NumPy with tifffile

tifffile reads the SVS pyramid directly, and its zarr store lets you slice the full-resolution image without decoding the rest of it.

import tifffile
import zarr

with tifffile.TiffFile("slide.svs") as tif:
print(tif.is_svs)                         # True for Aperio SVS
# Aperio stores its metadata as "key = value" pairs in the ImageDescription tag
description = tif.pages[0].description
meta = dict(item.split(" = ", 1) for item in description.split("|")[1:] if " = " in item)
print(meta.get("MPP"), meta.get("AppMag"))  # microns per pixel, scan magnification

levels = tif.series[0].levels             # the resolution pyramid
for level in levels:
print(level.shape, level.dtype)

small = levels[-1].asarray()              # the smallest level as a NumPy array

# Read a tile from full resolution without loading the whole slide
store = tif.aszarr(level=0)
z = zarr.open(store, mode="r")
tile = z[0:1024, 0:1024]                  # rows, columns, RGB
print(tile.shape)
store.close()

Output for CMU-1-JP2K-33005.svs

True
0.4990 20
(32893, 46000, 3) uint8
(8223, 11500, 3) uint8
(2055, 2875, 3) uint8
(1024, 1024, 3)

Note the shapes: tifffile reports (height, width, channels), the opposite order to OpenSlide's (width, height).

Cut a slide into tiles (for deep learning)

Most pipelines read fixed-size tiles from a lower-resolution level. read_region always takes level-0 coordinates, so scale each tile's position back up.

import openslide

slide = openslide.OpenSlide("slide.svs")
level = slide.get_best_level_for_downsample(4.1)  # about 4x smaller (see the note below)
scale = slide.level_downsamples[level]
width, height = slide.level_dimensions[level]
tile = 512

for y in range(0, height - tile + 1, tile):
for x in range(0, width - tile + 1, tile):
# read_region takes level-0 coordinates, so scale x and y back up
image = slide.read_region((int(x * scale), int(y * scale)), level, (tile, tile)).convert("RGB")
# e.g. image.save(f"tile_{x}_{y}.png") or feed it to a model
slide.close()

Why 4.1 and not 4? Stored downsamples are rarely exact: on our kidney slide level 1 is 4.0004×, and get_best_level_for_downsample(4) returns the level at or below 4, which is level 0. That silently tiles the full-resolution image instead: 1,365 tiles where 72 were intended. Asking for slightly more than you need picks the right level. For a model trained at a fixed resolution, choose the level from the microns per pixel instead of the downsample.

Errors you will probably meet

ErrorCauseFix
ModuleNotFoundError: Couldn't locate OpenSlide DLLopenslide-python is installed but the OpenSlide C library is notpip install openslide-bin
ValueError: <COMPRESSION.APERIO_JP2000_RGB: 33005> requires the 'imagecodecs' packageThe slide uses Aperio's JPEG 2000 compression (33003 or 33005)pip install imagecodecs
OpenSlideUnsupportedFormatError: Unsupported or missing image fileWrong path, an incomplete copy, or a file that is not a slideCheck the path and file size; openslide.OpenSlide.detect_format(path) returns 'aperio' for a readable SVS
MemoryError, or the process is killedReading level 0 in one pieceRead regions or tiles, or a smaller level

Which library should you use?

 openslide-pythontifffile + zarr
ReturnsPIL imagesNumPy arrays
Other formatsNDPI, MRXS, SCN, BIF, Philips TIFF, DICOM and more through one APITIFF-based formats, including OME-TIFF and NDPI
Best forTiling, thumbnails, slide properties, mixed scanner formatsArray workflows, dask or zarr pipelines, writing OME-TIFF
Installopenslide-python openslide-bintifffile imagecodecs zarr

For the format itself, the OpenSlide Aperio format notes describe how SVS files are laid out.

Just need to look at the slide?

Before you write code, it often helps to see the slide. On Windows, Leica's free Aperio ImageScope opens SVS files. On Windows or Mac, QuPath is free and open source. SlideScope is a paid desktop viewer with a free trial that opens SVS next to NDPI, MRXS, DICOM, CZI and ND2, shows the pyramid levels and microns per pixel in its metadata panel, and makes calibrated measurements. Our guide to opening SVS files compares every option.

SVS in Python: questions

How do I read an SVS file in Python?

Install openslide-python and openslide-bin with pip, then open the slide with openslide.OpenSlide("slide.svs"). read_region((x, y), level, (width, height)) returns a region as a PIL image, and get_thumbnail((1024, 1024)) returns an overview. For NumPy arrays, tifffile with imagecodecs and zarr reads any pyramid level or a tile of the full-resolution image.

How do I get microns per pixel from an SVS file?

With OpenSlide, read slide.properties[openslide.PROPERTY_NAME_MPP_X] (and MPP_Y). With tifffile, parse the "MPP = 0.4990" entry of the first page's ImageDescription, which Aperio writes as key = value pairs separated by |. The same description holds AppMag, the scan magnification.

Why does Python say it couldn't locate the OpenSlide DLL?

openslide-python is only the Python binding; the OpenSlide C library has to be installed too. Since openslide-python 1.4, pip install openslide-bin provides it as a wheel for Windows, macOS and Linux, and the error goes away.

Why can't tifffile read my SVS file?

Many SVS slides are compressed with Aperio's JPEG 2000 variants (TIFF compression 33003 or 33005). tifffile then raises "requires the 'imagecodecs' package". Install it with pip install imagecodecs.

Can I just look at an SVS file without writing code?

Yes. On Windows, Leica's free Aperio ImageScope opens SVS files. On Windows or Mac, QuPath is free and open source, and SlideScope is a paid desktop viewer with a free trial that opens SVS alongside NDPI, MRXS, CZI and ND2.

See your slide before you code it

Open your SVS in SlideScope to check levels, microns per pixel and where the tissue is. The free trial covers 10 of your own images or 3 days, no card needed.

Download SlideScope