A processor reads an image from a source, decodes it, transforms it according to request arguments, and encodes and writes a derivative image to the client. Particular processors can be assigned to handle particular source formats, and a fallback processor can be assigned to handle all others.
Different processors use different underlying codecs and image processing engines, which may have different quality, compatibility, dependency, performance, and cost characteristics. The ability to choose among different processors is intended to make it straightforward 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.
Different processors support different source formats. A table of supported formats is displayed in the Control Panel, as well as in the Supported Source Formats table 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).
Processors ultimately read images from sources, of which there are two main types: those that can supply files (FileSources), and those that can supply streams (StreamSources). Correspondingly, there are two types of processors: those that can read from files (FileProcessors), and those that can read from streams (StreamProcessors). These distinctions are important because they influence how data flows through the processing pipeline, which influences performance. Generally files are preferable to streams where performance is a priority.
FileProcessor | StreamProcessor (all of these can also function as FileProcessors) | |
FileSource
(only FilesystemSource) |
✓ | ✓ |
StreamSource
(all other sources) |
See Fallback Retrieval Strategy | See Stream Retrieval Strategy |
The table below is another way of expressing the same information:
S3 | Azure Storage | Filesystem | HTTP | JDBC | |
---|---|---|---|---|---|
FfmpegProcessor | * | * | ✓ | * | * |
GraphicsMagickProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
ImageMagickProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
JaiProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
Java2dProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
KakaduDemoProcessor | * | * | ✓ | * | * |
KakaduNativeProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
OpenJpegProcessor | * | * | ✓ | * | * |
PdfBoxProcessor | ✓ | ✓ | ✓ | ✓ | ✓ |
* Not natively compatible, but can work via an appropriate fallback retrieval strategy.
The stream retrieval strategy (processor.stream_retrieval_strategy
) controls how content is fed to stream-based processors from stream-based sources.
StreamStrategy
will try to stream a source image from a source when possible, and use the fallback retrieval strategy otherwise.DownloadStrategy
will download it to a temporary file, and delete it after the request is complete.CacheStrategy
will download it into the source cache using FilesystemCache, which must also be configured. This is significantly more efficient than DownloadStrategy
if you can spare the disk space.The fallback retrieval strategy (processor.fallback_retrieval_strategy
) controls how an incompatible StreamSource
/FileProcessor
combination is dealt with.
DownloadStrategy
will download a source image to a temporary file that the processor can read, and delete it after the request is complete.CacheStrategy
will download it into the source cache using FilesystemCache, which must also be configured. This is significantly more efficient than DownloadStrategy
if you can spare the disk space.AbortStrategy
will cause the request to fail.GraphicsMagick | ImageMagick | Java 2D | JAI | Kakadu Demo | Kakadu Native | 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 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Image overlays | × | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
String 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.
GraphicsMagick | ImageMagick | Java2D | JAI | Kakadu Demo | Kakadu Native | OpenJPEG | PDFBox | |
---|---|---|---|---|---|---|---|---|
BMP | ✓ | ✓ | ✓ | ✓ | × | × | × | × |
GIF | ✓ Animation not supported |
✓ Animation not supported |
✓ | × | × | × | × | × |
JPEG | ✓ | ✓ | ✓ | CMYK/YCCK not supported | × | × | × | × |
JPEG2000 | Uses JasPer (requires plugin); no level-reduction or ROI decoding | Uses OpenJPEG (requires delegate); no level-reduction or ROI decoding | × | × | ✓ | ✓ | ✓ | × |
Requires plugin | Requires delegate | × | × | × | × | × | ✓ | |
PNG | ✓ | ✓ | ✓ | ✓ | × | × | × | × |
TIFF | No multi-resolution or ROI decoding | No multi-resolution or ROI decoding | ✓ | ✓ | × | × | × | × |
WebP | Requires plugin | Requires delegate | × | × | × | × | × | × |
Java2dProcessor uses the Java Image I/O and Java 2D libraries to read and process images in a native-Java way. It is a good all-around processor with no dependencies.
This processor has been written to exploit the Image I/O 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.
Java Advanced Imaging (JAI) is a sophisticated image processing library developed by Sun Microsystems until the mid-2000s. It offers several advantages over Java 2D that make it ideal for an image server: a pull-based rendering pipeline that can reduce memory usage, and efficient region-of-interest decoding with some formats.
Development on JAI ended a long time ago, and a minor incompatibility has cropped up in Java 9. Given that supporting JAI is likely to become more problematic as time goes on, this processor should be considered deprecated, and it may be removed in a future release.
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 harmless and expected when there is no mediaLib JAR on the classpath. 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 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 can also support 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.
This processor was named KakaduProcessor in versions prior to 4.0. It was renamed in order to distinguish it from KakaduNativeProcessor, which is new in 4.0.
Kakadu is widely considered the fastest available general-purpose JPEG2000 codec. This processor uses Kakadu's kdu_expand demo application to decode JPEG2000 source images. All other operations are performed using Java 2D.
The Kakadu demo binaries must be installed in order for this processor to work. It's recommended to obtain these from the Kakadu website and install them per Kakadu's instructions.
Alternatively, the deps folder of the download archive contains prebuilt binaries for several platforms. kdu_expand will be detected automatically if it is on the path; otherwise, set the KakaduDemoProcessor.path_to_binaries
configuration key to the absolute path of the containing directory. The Kakadu shared library files will also need to be installed per the instructions in the KakaduNativeProcessor section.
Kakadu is not free software. This processor may be used in only one of the following ways:
Kakadu is a commercial JPEG2000 codec that is widely considered the fastest available general-purpose JP2 codec. In contrast to KakaduDemoProcessor, this processor calls directly into the Kakadu native library to decode JPEG2000 source images, which offers a number of benefits:
To get this processor to work, it must be able to locate the Kakadu JNI binding and shared library. The extracted release archive contains a folder named deps, which contains compiled binaries for several platforms. Copy the files from the platform-specific lib folder into one of the locations on the Java library path. These are logged at application startup in a message that looks like:
[main] INFO e.i.l.c.ApplicationContextListener - Java library path: .....
For Windows, you may also need to install Microsoft Visual C++ Redistributable, if it isn't already.
This processor was developed using a Kakadu Public Service License and may not be used commercially. See the Kakadu Software License Terms and Conditions for detailed terms.
OpenJpegProcessor uses the opj_decompress tool 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. All other operations are performed using Java 2D, and basic image characteristics are acquired using custom code.
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 has been tested with FFmpeg version 2.8. Other versions may or may not work.
FFmpeg is used only for frame extraction. All subsequent steps are handled by Java 2D.
This processor 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 of this argument 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 it's 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 arguments. The size of the base raster image, corresponding to a scale of 1, is configurable with the processor.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.