Several common source image formats are supported by at least one processor, but some are inherently better suited for high resolutions than others. In the table below, "pyramidal coding" refers to the ability of a format to support reduced-resolution decoding for preview or thumbnail images, and "region coding" refers to the ability to efficiently supply cropped regions—to zooming image viewers, for example.
Supports pyramidal coding | Supports region coding | Recommended for high-resolution source images | Recommended processor | ||
---|---|---|---|---|---|
BMP | × | × | × | Java2dProcessor | |
GIF | × | × | × | ||
JPEG | × | × | × | ||
JPEG2000 (notes) | ✓ | ✓ | ✓ | KakaduNativeProcessor, OpenJpegProcessor, or GrokProcessor | |
× | × | × | PdfBoxProcessor | ||
PNG | × | × | × | Java2dProcessor | |
TIFF (notes) | Striped | × | × | × | |
Tiled | × | ✓ | × | ||
Pyramidal Striped | ✓ | × | × | ||
Pyramidal Tiled | ✓ | ✓ | ✓ |
JPEG2000 uses advanced compression techniques to enable efficient reduced-scale and region-of-interest decoding. With a performant decoder, it is well-suited for use with very large source images.
KakaduNativeProcessor is the most efficient processor for this format, but it uses a commercial library that, while included, is only licensed for non-profit use.
OpenJpegProcessor uses the OpenJPEG codec, which is one of the fastest open-source JPEG2000 codecs.
GrokProcessor uses the Grok codec, an AGPL-licensed codec offering performance in between the two.
When serving TIFF source images, there are some criteria that source images must meet in order to be delivered efficiently.
The Adobe TIFF 6.0 specification permits arrangements of image data in either strips or tiles. Strips may consist of one or more whole rows of pixels, but tiles are typically square. By default, most TIFF encoders produce strip-based TIFFs, which are increasingly slow to read as their size increases. High-resolution TIFFs must be tile-based in order to permit efficient region extraction.
When using a Java Image I/O-based processor, information about TIFF source images is logged at debug level. These messages reveal whether a TIFF is strip-based or tile-based. For example, a request for a tiled TIFF will generate a log message like:
DEBUG e.i.l.c.p.c.TIFFImageReader - Acquiring region 0,0/500x500 from 8848x6928 image (128x128 tile size)
Pyramidal TIFFs can be read much more efficiently at reduced scales. In addition to the main image, a pyramidal TIFF file will contain a sequence of progressively half-scaled sub-images: for example, a 10000×10000 pixel main image would include variants of 5000×5000 pixels, 2500×2500 pixels, 1250×1250 pixels, and so on, in the same file.
Each of the images in a multi-resolution TIFF file can be striped or tiled, just as in a mono-resolution file. (They can even be encoded in other, non-TIFF formats.) Tiled and pyramidal encodings are complementary: the former improves efficiency with reduced regions at large scales, and the latter improves efficiency at reduced scales. For efficient deep zooming, TIFF images need to be pyramidal, and each level of the pyramid must be tiled.
Some image formats, like PDF and TIFF, can accommodate multiple embedded subimages. These can be accessed by supplying a page number in the URI identifier—see meta-identifiers.
A client may want to know how many such pages an image file contains. As the IIIF Image API has no concept of pages, the recommended technique is to implement the extra_iiifn_information_response_keys()
delegate methods, exposing the page_count
key of the delegate context. For example:
The client can then parse the JSON exposed by the information endpoint (info.json) of any of the pages to obtain the page count.
Every source image is considered to have a unique identifier, which appears in endpoint URIs and is used to reference the image throughout the application.
Identifiers may be the same as, or may map to, filenames, pathnames, object keys, or some other identifying token in the underlying storage. The Getting Started section describes a simple setup in which URI identifiers map to pathname fragments on a filesystem, but this can make for identifiers that are ugly, unstable, and/or insecure. See Sources for information on setting up your underlying storage to meet your particular use case.
An identifier references a unique source image file, but for some images, more specificity may be needed. For example, an "image" like a PDF document may contain multiple pages, each of which is considered a separate image. A page number can be appended to the PDF's identifier to create a meta-identifier that can be supplied to an IIIF Image API endpoint in order to convey this extra information to the endpoint that its API does not natively support.
Meta-identifiers rely on a transformer object that performs serialization and deserialization (i.e. converting to and from the form appearing in the URL). There are two such transformers available, selectable using the meta_identifier.transformer
configuration key:
This is the out-of-the-box default transformer, supporting the following formats:
identifier
identifier;page_number
identifier;scale_constraint
identifier;page_number;scale_constraint
The default component delimiter is a semicolon, but this can be changed using the meta_identifier.transformer.StandardMetaIdentifierTransformer.delimiter
configuration key.
This transformer invokes a pair of delegate methods to enable full control over serialization and deserialization (and, therefore, the precise format of the meta-identifiers). See the documentation of the deserialize_meta_identifier()
and deserialize_meta_identifier()
methods in the sample delegate script for more information.
Both slashes and URI-illegal characters in identifiers must be URI-encoded. For example, an image with an identifier of a6/b3/c4(d).jp2 would need to appear in a URI as a6%2Fb3%2Fc4%28d%29.jp2. When the application is behind a reverse proxy that cannot pass through encoded slashes (%2F) without decoding them, the slash_substitute
configuration key can be used to specify a different character or character sequence to treat as a slash.
Though an image may have samples larger than 8 bits, all output is limited to 8 bits (24-bit RGB or 32-bit ARGB).
Most processors support embedded color profiles and will either automatically copy them into derivative images or automatically adjust the output pixels; see the table of processor-supported features.
See Metadata.