IIIF – The International Image Interoperability Framework

IIIF

The International Image Interoperability Framework (IIIF) is an open API for standardized image retrieval created by a community of the world’s leading research libraries, major national libraries and not-for-profit image repositories in an effort to collaboratively produce an interoperable technology and community framework for image delivery.

These include the research libraries of the universities of Stanford, Yale, Harvard, Cornell and Oxford University’s Bodleian Library. National Libraries including the British Library, the BNF (the French national library) and the Royal Library of Denmark. And not-for-profit image repositories including the Wellcome Trust’s Library.

The goals of the project are to:

  • Give scholars an unprecedented level of uniform and rich access to image-based resources hosted around the world
  • Define a set of common application programming interfaces (APIs) that support interoperability between image repositories
  • Develop, cultivate and document shared technologies, such as image servers and web clients, that provide a world-class user experience in viewing, comparing, manipulating and annotating images

IIIF consists of an image API and a presentation API. The Presentation API provides structural and presentation information, whereas the image API provides a standard image delivery API.

The image API syntax is essentially the following:

{http/https}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}

where it is possible to specify a region within an image, the size at which the image should be output, rotation, mirroring and whether the output should be output as grayscale or color. Sizes can be expressed in either absolute pixels or percentages.

For example, to export an image test.tif uncropped, resized to 400×400 pixels, rotated by 90° and converted to greyscale, use the following URI:

test.tif/full/400,400/90/grey.jpg

Image metadata and a list of server capabilities is available through an info.json request, which provides information on the image and the functionality provided by the image server:

test.tif/info.json

The IIPImage server, iipsrv fully supports all current and previous versions of the image API (versions 1, 2 and 3) and is the most widely used IIIF image server.

The IIIF image API defines 3 levels of compliance with relation to the specification: 0, 1 and 2, where 2 is the highest level of compliance. The latest version of iipsrv is fully level 2 compliant and additionally supports optional advanced IIIF features such as mirroring and resizing to > 100%. The server also fully passes all IIIF validator conformance tests.

The API can be used in parallel to the existing IIPImage support for the IIP, DeepZoom and Zoomify APIs within both iipsrv and iipmooviewer.

More information on the IIIF initiative is available from the IIIF website, including a showcase of IIIF in action, which includes, of course, IIPImage:

IIPImage and IIIF: iipsrv and iipmooviewer using the IIIF protocol (click to open viewer)

Using IIIF with iipsrv, the IIPImage server

iipsrv supports several image APIs and requests need to specify which to use. To use IIIF, a CGI request should be provided of the form IIIF=<IIIF request>, where the IIIF API syntax described above forms the argument to this. A typical IIIF request will, therefore, look like the following:

http://your.server/fcgi-bin/iipsrv.fcgi?IIIF=image.tif/full/400,400/90/default.jpg

where http://your.server/fcgi-bin/iipsrv.fcgi is the URL to your running iipsrv instance, IIIF= is the CGI request that indicates to iipsrv that this is an IIIF request and image.tif/full/400,400/90/default.jpg is the IIIF API request itself.

Clean URLs

It is, however, possible to use cleaner URLs that eliminate the FCGI prefix and which avoid having to use the above iipsrv-specific command or query parameters. A cleaner version of the URL above would be, for example:

http://your.server/iiif/image.tif/full/400,400/90/default.jpg

To enable such clean URLs, you can either use iipsrv’s own default URI mapping mechanism or carry out URL-rewriting at the web server level in order to map this URL internally to the full path shown previously.

URI Mapping

iipsrv is able to perform URI mapping where a prefix can be defined that eliminates FCGI paths and query parameters. To use this functionality, iipsrv’s URI_MAP startup parameter can be used that is able to map an arbitrary URL prefix to any one of iipsrv’s supported APIs, including IIIF. This enables iipsrv to be able to work without full CGI query strings. The URI map must be of the form “prefix=>protocol” where prefix can be either empty or any arbitrary string prefix and protocol must be one of iipsrv supported protocols / APIs: IIP, IIIF, DeepZoom, Zoomify.

To enable URI mapping with Apache and mod_fcgid, for example, add this to the Apache configuration file:

FcgidInitialEnv URI_MAP "iiif=>IIIF"

This allows URI’s of the form http://server/iiif/ to be mapped to iipsrv’s IIIF protocol handler without requiring any external web server rewriting.

To make this work, make sure your web server is configured to forward requests for the path /iiif instead of /fcgi-bin/iipsrv.fcgi to iipsrv. For example for lighttpd:

fastcgi.server = ( "/iiif" =>
   (( "host" => "127.0.0.1",
      "port" => 9000,
      "check-local" => "disable",
      "bin-path" => "/usr/lib/cgi-bin/iipsrv.fcgi",
       "bin-environment" => (
        "URI_MAP" => "iiif=>IIIF"
       )
   ))
)

URL Rewriting

If you don’t wish or are unable to use iipsrv’s default URI mapping mechanism, it is possible to perform URL rewriting directly via your web server. Most web servers include functionality to achieve this, allowing any URL to be mapped internally to another.

For Apache and mod_rewrite use the following:

RewriteRule ^/iiif/$ /fcgi-bin/iipsrv.fcgi?IIIF=

For Lighttpd and_mod_rewrite:

url.rewrite-once = (
  "^/iiif/(.*)"  => "/fcgi-bin/iipsrv.fcgi?IIIF=$1"
)

Similarly for NginX and ngx_http_rewrite_module:

merge_slashes off;
rewrite ^/iiif/(.*) /fcgi-bin/iipsrv.fcgi?IIIF=%2F$1 last;

IIIF API Version Switching

The IIPImage server is fully compliant with all IIIF image API versions from 1.0 through to the current version 3.0. The syntax of versions 2.x is largely backward compatible with versions 1.x. However, version 3 of the API introduces some non-compatible changes to the syntax of the info.json response, which iipsrv has to handle. As there is still a large user base of IIIF version 2.x software, it will take some time until the 3.0 image API is fully deployed and supported. iipsrv, therefore, allows the setting of a default API version and the ability to set the API version per-user through HTTP content negotiation.

Default IIIF API Version

The default IIIF Image API version can be set using the IIIF_VERSION server directive. This is set once at start-up and defines a default IIIF image API version. For example, if starting iipsrv through Apache and mod_fcgid, add the following to your configuration to specify the use of version 2.x by default (note that only the major version should be specified: 1, 2, 3 etc):

FcgidInitialEnv IIIF_VERSION "2"

It may sometimes be useful to have separate URL end-points for each IIIF API version. This allows you to redirect different clients to appropriate canonical URLs, such as:

https://your.server/iiif2/image.tif/info.json (IIIF Image API version 2)
https://your.server/iiif3/image.tif/info.json (IIIF Image API version 3)

Content Negotiation

In addition to setting a default API version, the IIPImage server can also handle multiple IIIF versions from a single instance of iipsrv through the use of content negotiation. This makes use of standard HTTP Accept headers by the client for an info.json request. In order to specify a particular API version, add a application/ld+json content-type and profile to the Accept header list. For example, to specifically request version 3 of the IIIF image API, add the following:

application/ld+json;profile="http://iiif.io/api/image/3/context.json"

This can, of course, be combined with other mime-types. A typical full Accept header from Firefox would look something like this, where each mime type is separated by a comma:

Accept: text/html, application/xhtml+xml, application/xml;q=0.9, application/ld+json;profile="http://iiif.io/api/image/3/context.json"

The IIPImage server will parse the header and then format the info.json output based on the supplied IIIF context. If no version preference has been set in this way or if the header has been incorrectly formatted, the default IIIF API version will be used.

Caching Issues

The use of per-request content negotiation creates potential issues with respect to caching. info.json requests that specify a version that is different to the default have their HTTP Content-Control header set to private by iipsrv to avoid caching by shared caches between the server and client. In addition, these info.json responses are not cached internally by iipsrv when using Memcached.

IIPMooViewer

IIIF is also supported client-side within iipmooviewer, allowing iipmooviewer to be used with any IIIF compliant server.

To use IIIF, simply specify IIIF as the protocol and make sure the server parameter points to the IIIF-enabled end-point. For example, this would be /iiif/ if you are using iipsrv and have enabled URL rewriting. Otherwise this would be the full path: /fcgi-bin/iipsrv.fcgi?IIIF=

// iipmooviewer constructor
  new IIPMooViewer( "viewer", {
     server: "/iiif/",
     image: "image.tif",
     protocol: "IIIF"
  });

See the iipmooviewer documentation for more details on other iipmooviewer functionality.