Processors are responsible for reading source images from resolvers and transforming them according to request parameters. Processors are modular and pluggable. Particular processors can be assigned to handle particular source formats, and a fallback processor can be assigned to all others.
Different processors have different quality, compatibility, dependency, and performance characteristics. The ability to choose among different processors is intended to make it easy to add support for new image formats; improve support for existing image formats via the substitution of better codecs; and decouple the image server implementation from any one codec.
In terms of format support, a distinction is made between the concepts of source format and output format. Available output formats may differ on a per-platform or per-instance basis depending on the source format.
Supported source formats depend on the processor, and possibly installed libraries/delegates, etc., as well. Lists of these are displayed on the landing page, as well as in one of the tables below. A list of output formats supported for a given source format is contained within the response to an information request (such as /iiif/2/{identifier}/info.json).
Linux | macOS | Windows | |
---|---|---|---|
FfmpegProcessor | ✓ | ✓ | ✓ |
GraphicsMagickProcessor | ✓ | ✓ | ✓ |
ImageMagickProcessor | ✓ | ✓ | ✓ |
JaiProcessor | ✓ | ✓ | ✓ |
Java2dProcessor | ✓ | ✓ | ✓ |
KakaduProcessor | ✓ | ✓ | |
OpenJpegProcessor | ✓ | ✓ | |
PdfBoxProcessor | ✓ | ✓ | ✓ |
Amazon S3 | Azure Storage | Filesystem | HTTP | JDBC | |
---|---|---|---|---|---|
FfmpegProcessor | ✓* | ✓* | ✓ | ✓* | ✓* |
GraphicsMagickProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
ImageMagickProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
JaiProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
Java2dProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
KakaduProcessor | ✓* | ✓* | ✓ | ✓* | ✓* |
OpenJpegProcessor | ✓* | ✓* | ✓ | ✓* | ✓* |
PdfBoxProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
✓*: Not natively compatible, but will work if the source cache is enabled
GraphicsMagick | ImageMagick | Java 2D | JAI | Kakadu | OpenJPEG | FFmpeg | PDFBox | |
---|---|---|---|---|---|---|---|---|
Mirroring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Region by percent | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Region by pixels | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Square region | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Arbitrary rotation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Rotation by 90°s | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Upsizing | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by whitelisted/confined width/height | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by forced/distorted width/height | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by height | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by width | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by percent | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Size by width/height | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Grayscale output | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Bitonal output | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Overlays | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
Redaction | ✓ | ✓ | ✓ | ✓ | ✓ | |||
Tiled reading | ✓ | ✓ | ✓ | ✓ | N/A | N/A | ||
Multiresolution reading | ✓ | ✓ | ✓ | ✓ | N/A | N/A | ||
Copying metadata into derivatives of same format | ✓ | ✓ | ✓ | ✓ | N/A | N/A | ||
ICC profiles | ✓* | ✓* | ✓* | ✓* | ✓* | ✓** | N/A | |
Awareness of EXIF Orientation tag | ✓ | ✓ | ✓ | ✓ | N/A | N/A | ||
Selectable resample filters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Sharpening | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Normalization | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
✓*: Copied into derivative images.
✓**: Derivative image pixel data is modified according to the ICC profile.
BMP | DICOM | GIF | JPEG | JPEG2000 | PNG | TIFF | WebP | ||
---|---|---|---|---|---|---|---|---|---|
GraphicsMagickProcessor | ✓ | ✓ | ✓ | ✓ | Uses JasPer (requires plugin). No level-reduction or region decoding. | Requires plugin; no source DPI control | ✓ | All aspects, but no multi-resolution or ROI decoding | Requires plugin |
ImageMagickProcessor | ✓ | ✓ | ✓ | ✓ | Uses OpenJPEG (requires delegate). No level-reduction or region decoding. | Requires delegate; no source DPI control | ✓ | All aspects, but no multi-resolution or ROI decoding | Requires delegate |
JaiProcessor | ✓ | Generally supported, but not extensively tested | ✓ | RGB, 8-bit, baseline, line-interlaced, plane-interlaced | RGB, RGBA, 8-bit | RGB, RGBA; 8-bit, 16-bit; uncompressed, PackBits, LZW, ZIP, JPEG (8-bit only); striped, tiled, and multi-resolution reading; BigTIFF | |||
Java2dProcessor | ✓ | Generally supported, but not extensively tested | ✓ | RGB, 8-bit, baseline, line-interlaced, plane-interlaced | RGB, RGBA, 8-bit | RGB, RGBA; 8-bit, 16-bit; uncompressed, PackBits, LZW, ZIP, JPEG (8-bit only); striped, tiled, and multi-resolution reading; BigTIFF | |||
KakaduProcessor | ✓ | ||||||||
OpenJpegProcessor | ✓ | ||||||||
PdfBoxProcessor | ✓ |
Java2dProcessor uses the Java ImageIO and Java 2D libraries to read and process images in a native-Java way. It is a good all-around processor with no external dependencies.
Java2dProcessor has been written to exploit the ImageIO image readers as efficiently as possible. Special attention has been paid to its handling of tiled images, such as tile-encoded TIFFs, for which it reads only the necessary tiles for a given request. It is also capable of reading the sub-images contained within multi-resolution (pyramidal) TIFF images.
Because this processor does all its work in Java, it places a burden on the JVM heap. Although it tries to be efficient at reading images, it does have to create new derivative images at every processing step (scaling, rotating, etc.), which can cause transient spikes in memory usage. (See the section on memory considerations.)
Java Advanced Imaging (JAI) is a sophisticated image processing library developed by Sun Microsystems from the late 1990s to the mid-2000s. It offers several advantages over Java 2D: a pull-based rendering pipeline that can reduce memory usage, and efficient region-of-interest decoding with some formats.
As JaiProcessor uses the same ImageIO readers and writers as Java2dProcessor, it can read and write the same formats.
Years ago, Sun published platform-native accelerator JARs called mediaLib for Windows, Linux, and Solaris, which improved JAI's performance. It is unknown whether these still work on modern platforms, or what degree of benefit they provide.
Note: When using this processor, it is normal to see the following log message:
Error: Could not find mediaLib accelerator wrapper classes. Continuing in pure Java mode.
This is caused by the absence of a mediaLib JAR on the classpath, and is harmless. Add the -Dcom.sun.media.jai.disableMediaLib=true
VM option to suppress it.
GraphicsMagickProcessor invokes the GraphicsMagick executable (gm). GraphicsMagick is not included and must be installed separately.
GraphicsMagick produces high-quality output and supports all of the IIIF transforms and most IIIF output formats (assuming the necessary libraries are installed; see Supported Formats).
GraphicsMagickProcessor is usually faster than ImageMagickProcessor. However, like ImageMagickProcessor, it is neither tile- nor multi-resolution-aware and thus fares poorly with large images.
GraphicsMagickProcessor supports a page
URL query argument (which is nonstandard and Cantaloupe-specific) which can be used to return a particular page of a PDF. For example:
http://example.org/iiif/2/document.pdf/full/full/0/default.jpg?page=2
If the page
argument is missing, the first page will be returned.
ImageMagickProcessor invokes ImageMagick commands—either convert
and identify
(version 6 and below) or magick
(version 7+). (The version will be autodetected at startup.) ImageMagick is not included and must be installed separately.
ImageMagick supports all of the IIIF transforms and all IIIF output formats, assuming the necessary delegates are installed. It also supports a wide array of source formats.
ImageMagick offers excellent output quality at the expense of performance, which suffers increasingly as image size increases.
ImageMagickProcessor supports a page
URL query argument (which is nonstandard and Cantaloupe-specific) which can be used to return a particular page of a PDF. For example:
http://example.org/iiif/2/document.pdf/full/full/0/default.jpg?page=2
If the page
argument is missing, the first page will be returned.
KakaduProcessor uses the kdu_expand and kdu_jp2info binaries from the Kakadu SDK to efficiently decode JPEG2000 source images. This processor is capable of performing well even with large JP2s. Kakadu is extensively optimized and will make use of all available CPU cores.
kdu_expand is mainly a decompression tool, and Cantaloupe uses only its cropping and level-reduction features. All other operations (differential scaling, rotation, etc.) are performed using Java 2D.
To use this processor, Kakadu must be installed. (See the note below.) The Kakadu binaries will automatically be detected if they are on the path; otherwise, set the KakaduProcessor.path_to_binaries
configuration key to the absolute path of the containing directory. The LD_LIBRARY_PATH
environment variable will also need to be set to locate the Kakadu shared library.
OpenJpegProcessor uses the opj_decompress and opj_dump tools from the open-source OpenJPEG project to decode JPEG2000 source images.
Although it does support some other operations, opj_decompress is mainly a decompression tool, and Cantaloupe uses only its cropping and level-reduction features. The rest of the IIIF operations (differential scaling, rotation, etc.) are performed using Java 2D.
To use this processor, OpenJPEG must be installed. The OpenJPEG binaries will automatically be detected if they are on the path; otherwise, set the OpenJpegProcessor.path_to_binaries
configuration key to the absolute path of the containing directory. The LD_LIBRARY_PATH
environment variable will also need to be set to locate the OpenJPEG shared library.
FfmpegProcessor uses the FFmpeg tool to extract still frames from video files. It can be used for thumbnail generation รก la YouTube, as well as deep zooming of high-resolution still frames.
FfmpegProcessor has been tested with FFmpeg version 2.8. Other versions may or may not work.
Prior to Cantaloupe 3.3, FFmpeg itself handled all post-processing steps. Now, it is used only to decode still frames, and all subsequent steps are handled by Java 2D.
FFmpegProcessor supports a time
URL query argument (which is nonstandard and Cantaloupe-specific) which can be used to return a frame at a particular second in the source video. The value should be in hh:mm:ss
format, like:
http://example.org/iiif/2/video.mp4/full/full/0/default.jpg?time=00:02:15
If the time
argument is missing, the first frame will be returned.
PdfBoxProcessor uses the Apache PDFBox library to read and rasterize PDF files. This is a pure-Java library that is bundled in and has no dependencies.
As PDF is a vector format, PdfBoxProcessor will convert to a raster (pixel) image and use a Java 2D pipeline to transform it according to the request parameters.
The size of the default raster image, corresponding to a scale of one, is configurable with the PdfBoxProcessor.dpi
configuration option. When a request asks for a scale of ≤ 50% or ≥ 200%, a fraction or multiple of this will be used, respectively, in order to improve efficiency at small scales, and detail at large scales.
PdfBoxProcessor supports a page
URL query argument (which is nonstandard and Cantaloupe-specific) which can be used to return a particular page of a PDF. For example:
http://example.org/iiif/2/document.pdf/full/full/0/default.jpg?page=2
If the page
argument is missing, the first page will be returned.