IIIF without an image server? No problem! Simeon Warner (Cornell) https ://orcid.org/0000-0002-7970-7855 2017 IIIF Conference, The Vatican 8 June 2017
IIIF without an image
server? No problem!
Simeon Warner (Cornell)
https://orcid.org/0000-0002-7970-7855
2017 IIIF Conference, The Vatican
8 June 2017
Who are you?
1. Who has used IIIF in some form already?
2. Who feels they understand the distinction
between the IIIF Image and Presentation
APIs?
3. Who understands the contents of an IIIF
Image API “info.json” file (response to
Image Information Request)?
http://iiif.io/api/image/2.1/
http://iiif.io/api/presentation/2.1/
Punchline: You can use IIIF
applications on images and manifests
that are simply static files on a web-
server
In this talk I will focus on doing this to
support the Image API, support for
manifests and other Presentation API
JSON files is trivial
IIIF Image API “level 0” compliance
Every Image API info.json must have the compliance level specified in the profile:
Values are defined in the Image API Compliance
document: http://iiif.io/api/image/2.1/compliance/
“level 0” means
Only the following parameter values are supported:
• region=“full” except for tiles generates
according to the tiles values
• size=“full” except for values in sizes or tiles
generated according to the tiles values
• rotation=0
• quality=“default”
• format=“jpg”
But this is enough to pan and zoom.
IIIF Image API to support viewers
• The 90% (or is it 99%?) use-case for the IIIF Image API
is driving tile-based rich pan and zoom viewers
• The most popular IIIF viewers are currently the
Universal Viewer and Mirador
• Both of these viewers are based around the
OpenSeadragon viewer library
• ...so, to support these viewers one needs to cater
for the needs of OpenSeadragon
What does OpenSeadragon need?
[07/Jun/2017 05:32:44] "GET /starfish/info.json HTTP/1.1”
[07/Jun/2017 05:32:44] "GET /starfish/full/375,/0/default.jpg HTTP/1.1”
[07/Jun/2017 05:32:44] "GET /starfish/full/750,/0/default.jpg HTTP/1.1”
[07/Jun/2017 05:33:31] "GET /starfish/0,0,2048,2048/1024,/0/default.jpg
HTTP/1.1”
[07/Jun/2017 05:33:31] "GET /starfish/0,2048,2048,1952/1024,/0/default.jpg
HTTP/1.1”
[07/Jun/2017 05:33:32] "GET /starfish/2048,0,952,2048/476,/0/default.jpg
HTTP/1.1”
[07/Jun/2017 05:33:32] "GET
/starfish/2048,2048,952,1952/476,/0/default.jpg HTTP/1.1”
[07/Jun/2017 05:33:32] "GET
/starfish/1024,1024,1024,1024/1024,/0/default.jpg HTTP/1.1”
[07/Jun/2017 05:33:32] "GET
/starfish/1024,2048,1024,1024/1024,/0/default.jpg HTTP/1.1”
[07/Jun/2017 05:34:17] "GET /starfish/0,1024,1024,1024/1024,/0/default.jpg
HTTP/1.1”
info.json
small full
tiles
Tile requests
OpenSeadragon uses the width and scaleFactors
values in the tiles parameter to generate tile
requests:
There is some fiddly arithmetic to deal with partial
tiles at the lower and right edges of the image. This is
described in http://iiif.io/api/image/2.1/#a-
implementation-notes
Scaled full region requests
The dirty secret here is that OpenSeadragon does not follow the scaled sizes declared in the sizes
parameter.
Instead it requests a set of images scaled by factors of
two. One must generate tiles in these sizes with care
to replicate the rounding, see https://github.com/zimeon/iiif/blob/v1.0.4/iiif/static.py#L82-L89
A static tile generator
https://github.com/zimeon/iiif/tree/master/demo-static
Tile generation./iiif_static.py --write-html demo-static -d demo-static -t 1024
testimages/starfish.jpg
iiif_static.py: source file: testimages/starfish.jpg
iiif.static: demo-static / starfish/0,0,1024,1024/1024,/0/default.jpg
iiif.static: demo-static / starfish/0,1024,1024,1024/1024,/0/default.jpg
iiif.static: demo-static / starfish/0,2048,1024,1024/1024,/0/default.jpg
iiif.static: demo-static / starfish/0,3072,1024,928/1024,/0/default.jpg
…
iiif.static: demo-static / starfish/2048,2048,952,1952/476,/0/default.jpg
iiif.static: demo-static / starfish/full/750,/0/default.jpg
iiif.static: demo-static / starfish/full/750,1000 -> starfish/full/750,
iiif.static: demo-static / starfish/full/375,/0/default.jpg
iiif.static: demo-static / starfish/full/375,500 -> starfish/full/375,
…
iiif.static: demo-static / starfish/full/1,1 -> starfish/full/1,
iiif.static: demo-static / starfish/info.json
iiif.static: Writing HTML to demo-static
iiif.static: demo-static / starfish.html
Local demo
Serve info.json, tiles
and OpenSeadragon
from local test server
Usual OpenSeadragon
experience
How many tiles will there be? And
how big will they be?
• There will be approximately ¼ as many tiles at the
second zoom level than the first, 1/16 at the second
etc. and the sum of this series 1 + ¼ + 1/16 ... = 4/3
• Thus we can estimate the number of tiles:
ceil( ceil(width/tilesize)*ceil(height/tilesize) * 4/3)
• The total size of the tiles will likely be similar to the
original image size (assuming the same level of
compression; starting from TIFF tiles will likely be
much smaller than the original)
CORS: Access-Control-Allow-Origin
“Servers should send the Access-Control-Allow-Origin
header with the value * in response to information
requests. The syntax is shown below and is described
in the CORS specification. This header is required in
order to allow the JSON responses to be used by Web
applications hosted on different servers.”
Access-Control-Allow-Origin: *
You can get away without CORS only if the JavaScript
client is served from the same host as the images, and
thus the images are not reusable.
CORS setup
Apache instructions along with the
IIIF Image API specification http://iiif.io/api/annex/notes/apache/#enabling-
cors
Also easy to enable on AWS S3
(screenshot) and other serviceshttps://docs.aws.amazon.com/AmazonS3/latest/
dev/cors.html
Need to set up a user
(preferably using AWS
IAM system and assign
permissions to update
bucket, record key and
secret
...takes a few screens
and a little reading...
And set up CORS on bucket.
Gotcha: You’ll only see the Access-
Control-Allow-Origin in responses
requests with an Origin header, e.g.:
> curl -H "Access-Control-Request-Method: GET" -
H "Origin: http://example.com" -I http://iiif-static-
demo.s3-website.us-east-
2.amazonaws.com/vatlib/info.json
HTTP/1.1 200 OK
...
x-amz-request-id: 102493024334B199
Date: Wed, 07 Jun 2017 23:15:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD
Vary: Origin, Access-Control-Request-Headers,
Access-Control-Request-Method
Last-Modified: Wed, 07 Jun 2017 18:14:17 GMT
ETag: "da7fba981e2fd060c5b93a5d243895e8"
Content-Type: application/json
Content-Length: 1040
Server: AmazonS3
Generate tiles and copy to S3
iiif_static.py -p http://iiif-static-demo.s3-website.us-
east-2.amazonaws.com -d tmp --write-html=tmp --
include-osd --extra=full/106, vatlib.jpg
aws s3 sync tmp s3://iiif-static-demo --grants
read=uri=http://acs.amazonaws.com/groups/global/Al
lUsers
Image info.json:
http://iiif-static-demo.s3-website.us-east-
2.amazonaws.com/vatlib/info.json
Manually created a simple manifest:
http://iiif-static-demo.s3-website.us-east-
2.amazonaws.com/manifest.json
Same simple OpenSeadragon demo
Same as previous
demo running on
local machine
BUT can now refer
to image and
Presentation API
manifest...
Enter manifest URI, then shows on list
Mirador demo site
http://projectmirador.org/demo/ ,
select “Replace Object”
UV load fails (endlessly spinning icon)
because the JavaScript is HTTPS, image
information and tiles are HTTP
Unfortunately, one has to use CloudFront to
get HTTPS on an S3 website
HTTPS and mixed-content
• All of the IIIF specs work over either HTTP
or HTTPS (though you shouldn’t use
authentication with HTTP)
• BUT, plain HTTP and HTTPS do not play
well together, see e.g. https://www.jack-
reed.com/2017/05/23/the-case-for-serving-your-iiif-
content-over-https.html
• “IIIF ceases to be interoperable if you
don't make all your resources available
over HTTPS, because you're effectively
denying access to secure clients” @tomcrane
the bottom line (literally) is:
HTTPS – Just do it!
Static IIIF A/V – yes!
• Current work toward IIIF A/V support (see:
https://github.com/IIIF/iiif-
av/blob/master/source/api/av/index.md ) imagines
most base functionality, supporting many of our
current use cases, being provided through “level-0”
implementation
• Common web video standards such as MPEG-DASH
and HLS provide flexible access to time-ranges etc.
through indexing schemes and simple byte-range
requests that are part of ordinary web servers
(including cloud services such as S3).
• Current understanding is that an equivalent of
“info.json” will be required to allow auth with A/V