Spaces:
Running
Running
Create docs.md
Browse files
docs.md
ADDED
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# IIIF APIs Reference (Image API 3.0 & Presentation API 3.0)
|
2 |
+
|
3 |
+
## Overview
|
4 |
+
|
5 |
+
The IIIF (International Image Interoperability Framework) consists of complementary APIs for delivering and presenting digital content:
|
6 |
+
|
7 |
+
- **Image API**: Web service for image manipulation and delivery via URI parameters
|
8 |
+
- **Presentation API**: JSON-LD format for describing structure, metadata, and presentation of compound digital objects
|
9 |
+
- **Content Search API**: Full-text search within IIIF resources
|
10 |
+
|
11 |
+
## IIIF Image API 3.0
|
12 |
+
|
13 |
+
## URI Syntax
|
14 |
+
|
15 |
+
### Base URI Template
|
16 |
+
```
|
17 |
+
{scheme}://{server}{/prefix}/{identifier}
|
18 |
+
```
|
19 |
+
|
20 |
+
### Image Request URI Template
|
21 |
+
```
|
22 |
+
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
|
23 |
+
```
|
24 |
+
|
25 |
+
### Image Information Request URI Template
|
26 |
+
```
|
27 |
+
{scheme}://{server}{/prefix}/{identifier}/info.json
|
28 |
+
```
|
29 |
+
|
30 |
+
## URI Components
|
31 |
+
|
32 |
+
| Component | Description |
|
33 |
+
|-----------|-------------|
|
34 |
+
| scheme | HTTP or HTTPS protocol |
|
35 |
+
| server | Host server (may include port number) |
|
36 |
+
| prefix | Optional path to the service on the host server |
|
37 |
+
| identifier | Identifier of the requested image (ARK, URN, filename, etc.) |
|
38 |
+
|
39 |
+
**Important**: Special characters in identifiers MUST be URI encoded, including slashes (/).
|
40 |
+
|
41 |
+
## Image Request Parameters
|
42 |
+
|
43 |
+
Parameters must be specified in this exact order: region/size/rotation/quality.format
|
44 |
+
|
45 |
+
### Region Parameter
|
46 |
+
|
47 |
+
Defines the rectangular portion of the image to return.
|
48 |
+
|
49 |
+
| Form | Description | Example |
|
50 |
+
|------|-------------|---------|
|
51 |
+
| `full` | Return the complete image | `full` |
|
52 |
+
| `square` | Return square region (shorter dimension) | `square` |
|
53 |
+
| `x,y,w,h` | Pixel coordinates (x,y) and dimensions (w,h) | `125,15,120,140` |
|
54 |
+
| `pct:x,y,w,h` | Percentage coordinates and dimensions | `pct:41.6,7.5,40,70` |
|
55 |
+
|
56 |
+
### Size Parameter
|
57 |
+
|
58 |
+
Specifies dimensions for scaling the extracted region.
|
59 |
+
|
60 |
+
| Form | Description | Example |
|
61 |
+
|------|-------------|---------|
|
62 |
+
| `max` | Maximum size available (no upscaling) | `max` |
|
63 |
+
| `^max` | Maximum size (allows upscaling) | `^max` |
|
64 |
+
| `w,` | Scale to exact width | `150,` |
|
65 |
+
| `^w,` | Scale to exact width (allows upscaling) | `^200,` |
|
66 |
+
| `,h` | Scale to exact height | `,100` |
|
67 |
+
| `^,h` | Scale to exact height (allows upscaling) | `^,150` |
|
68 |
+
| `pct:n` | Scale to n percent (max 100%) | `pct:50` |
|
69 |
+
| `^pct:n` | Scale to n percent (allows upscaling) | `^pct:150` |
|
70 |
+
| `w,h` | Exact width and height (may distort) | `200,300` |
|
71 |
+
| `^w,h` | Exact width and height (allows upscaling) | `^250,400` |
|
72 |
+
| `!w,h` | Best fit within w,h (maintains aspect ratio) | `!200,300` |
|
73 |
+
|
74 |
+
### Rotation Parameter
|
75 |
+
|
76 |
+
Specifies mirroring and rotation to be applied to the image.
|
77 |
+
|
78 |
+
| Form | Description |
|
79 |
+
|------|-------------|
|
80 |
+
| `0` | No rotation |
|
81 |
+
| `90`, `180`, `270` | Clockwise rotation in degrees |
|
82 |
+
| `!0`, `!90`, etc. | Horizontal mirroring then rotation |
|
83 |
+
|
84 |
+
### Quality Parameter
|
85 |
+
|
86 |
+
Determines color characteristics of the image.
|
87 |
+
|
88 |
+
| Value | Description |
|
89 |
+
|-------|-------------|
|
90 |
+
| `default` | Server-determined default quality |
|
91 |
+
| `color` | Full color image |
|
92 |
+
| `gray` | Grayscale image |
|
93 |
+
| `bitonal` | Black and white image |
|
94 |
+
|
95 |
+
### Format Parameter
|
96 |
+
|
97 |
+
Specifies the output format.
|
98 |
+
|
99 |
+
Common formats: `jpg`, `png`, `gif`, `webp`, `tif`
|
100 |
+
|
101 |
+
---
|
102 |
+
|
103 |
+
## IIIF Presentation API 3.0
|
104 |
+
|
105 |
+
### Purpose
|
106 |
+
The Presentation API provides a standardized way to describe compound digital objects (books, manuscripts, albums, etc.) with their structure, metadata, and presentation instructions. It uses JSON-LD format to enable rich viewing experiences across different client applications.
|
107 |
+
|
108 |
+
### Core Resource Types
|
109 |
+
|
110 |
+
#### Collection
|
111 |
+
Ordered list of Manifests and/or other Collections for hierarchical organization.
|
112 |
+
```json
|
113 |
+
{
|
114 |
+
"@context": "http://iiif.io/api/presentation/3/context.json",
|
115 |
+
"id": "https://example.org/collection/books",
|
116 |
+
"type": "Collection",
|
117 |
+
"label": { "en": ["Book Collection"] },
|
118 |
+
"items": [
|
119 |
+
{
|
120 |
+
"id": "https://example.org/manifest/book1",
|
121 |
+
"type": "Manifest",
|
122 |
+
"label": { "en": ["Book 1"] }
|
123 |
+
}
|
124 |
+
]
|
125 |
+
}
|
126 |
+
```
|
127 |
+
|
128 |
+
#### Manifest
|
129 |
+
Describes a single compound object with its structure, metadata, and viewing instructions.
|
130 |
+
```json
|
131 |
+
{
|
132 |
+
"@context": "http://iiif.io/api/presentation/3/context.json",
|
133 |
+
"id": "https://example.org/manifest/book1",
|
134 |
+
"type": "Manifest",
|
135 |
+
"label": { "en": ["Example Book"] },
|
136 |
+
"summary": { "en": ["A description of this book"] },
|
137 |
+
"metadata": [
|
138 |
+
{
|
139 |
+
"label": { "en": ["Author"] },
|
140 |
+
"value": { "en": ["Jane Doe"] }
|
141 |
+
}
|
142 |
+
],
|
143 |
+
"items": [
|
144 |
+
{
|
145 |
+
"id": "https://example.org/canvas/page1",
|
146 |
+
"type": "Canvas",
|
147 |
+
"label": { "en": ["Page 1"] },
|
148 |
+
"height": 1000,
|
149 |
+
"width": 750,
|
150 |
+
"items": [
|
151 |
+
{
|
152 |
+
"id": "https://example.org/page/page1/annopage",
|
153 |
+
"type": "AnnotationPage",
|
154 |
+
"items": [
|
155 |
+
{
|
156 |
+
"id": "https://example.org/page/page1/anno",
|
157 |
+
"type": "Annotation",
|
158 |
+
"motivation": "painting",
|
159 |
+
"body": {
|
160 |
+
"id": "https://example.org/iiif/page1/full/max/0/default.jpg",
|
161 |
+
"type": "Image",
|
162 |
+
"format": "image/jpeg",
|
163 |
+
"service": [
|
164 |
+
{
|
165 |
+
"id": "https://example.org/iiif/page1",
|
166 |
+
"type": "ImageService3",
|
167 |
+
"profile": "level2"
|
168 |
+
}
|
169 |
+
]
|
170 |
+
},
|
171 |
+
"target": "https://example.org/canvas/page1"
|
172 |
+
}
|
173 |
+
]
|
174 |
+
}
|
175 |
+
]
|
176 |
+
}
|
177 |
+
]
|
178 |
+
}
|
179 |
+
```
|
180 |
+
|
181 |
+
#### Canvas
|
182 |
+
Virtual container representing a view of the object (page, image, time segment) with defined dimensions.
|
183 |
+
- **Spatial**: Uses `height` and `width` properties
|
184 |
+
- **Temporal**: Uses `duration` property
|
185 |
+
- **Mixed**: Can have all three dimensions
|
186 |
+
|
187 |
+
#### Range
|
188 |
+
Defines structural sections within an object (chapters, movements, articles).
|
189 |
+
```json
|
190 |
+
{
|
191 |
+
"id": "https://example.org/range/chapter1",
|
192 |
+
"type": "Range",
|
193 |
+
"label": { "en": ["Chapter 1"] },
|
194 |
+
"items": [
|
195 |
+
{ "id": "https://example.org/canvas/page1", "type": "Canvas" },
|
196 |
+
{ "id": "https://example.org/canvas/page2", "type": "Canvas" }
|
197 |
+
]
|
198 |
+
}
|
199 |
+
```
|
200 |
+
|
201 |
+
#### Annotation & Annotation Page
|
202 |
+
Content is associated with Canvases through Annotations collected in Annotation Pages.
|
203 |
+
- **Painting motivation**: Content that is part of the Canvas (images, video, audio)
|
204 |
+
- **Supplementing motivation**: Content derived from the Canvas (transcriptions, translations)
|
205 |
+
- **Other motivations**: Commentary, tags, etc.
|
206 |
+
|
207 |
+
### Essential Properties
|
208 |
+
|
209 |
+
#### Required Properties
|
210 |
+
- **id**: HTTP(S) URI identifier
|
211 |
+
- **type**: Resource class (Collection, Manifest, Canvas, etc.)
|
212 |
+
- **label**: Human-readable name (internationalized)
|
213 |
+
|
214 |
+
#### Key Descriptive Properties
|
215 |
+
- **metadata**: Array of label/value pairs for display
|
216 |
+
- **summary**: Brief description
|
217 |
+
- **thumbnail**: Representative image(s)
|
218 |
+
- **provider**: Institution/organization information
|
219 |
+
- **rights**: License or rights statement URI
|
220 |
+
- **requiredStatement**: Text that must be displayed (attribution)
|
221 |
+
|
222 |
+
#### Technical Properties
|
223 |
+
- **height/width**: Pixel dimensions for images, aspect ratio for Canvas
|
224 |
+
- **duration**: Time length in seconds
|
225 |
+
- **format**: MIME type (e.g., "image/jpeg")
|
226 |
+
- **profile**: Schema or functionality description
|
227 |
+
- **viewingDirection**: Display order (left-to-right, right-to-left, etc.)
|
228 |
+
- **behavior**: Presentation hints (paged, continuous, individuals, etc.)
|
229 |
+
|
230 |
+
#### Structural Properties
|
231 |
+
- **items**: Ordered list of child resources
|
232 |
+
- **structures**: Top-level Ranges for table of contents
|
233 |
+
- **annotations**: Commentary Annotation Pages
|
234 |
+
|
235 |
+
### Language Internationalization
|
236 |
+
Properties like `label`, `summary`, and `metadata` use language maps:
|
237 |
+
```json
|
238 |
+
{
|
239 |
+
"label": {
|
240 |
+
"en": ["English Title"],
|
241 |
+
"fr": ["Titre Français"],
|
242 |
+
"none": ["No Language"]
|
243 |
+
}
|
244 |
+
}
|
245 |
+
```
|
246 |
+
|
247 |
+
### Behavior Values
|
248 |
+
Control presentation and navigation:
|
249 |
+
|
250 |
+
| Behavior | Applies To | Description |
|
251 |
+
|----------|------------|-------------|
|
252 |
+
| `auto-advance` | Collections, Manifests, Canvases, Ranges | Automatically proceed to next item |
|
253 |
+
| `no-auto-advance` | Collections, Manifests, Canvases, Ranges | Do not auto-advance (default) |
|
254 |
+
| `paged` | Collections, Manifests, Ranges | Page-turning interface |
|
255 |
+
| `continuous` | Collections, Manifests, Ranges | Virtually stitch views together |
|
256 |
+
| `individuals` | Collections, Manifests, Ranges | Distinct objects/views (default) |
|
257 |
+
| `unordered` | Collections, Manifests, Ranges | No inherent order |
|
258 |
+
| `facing-pages` | Canvases | Canvas shows both parts of opening |
|
259 |
+
| `sequence` | Ranges | Alternative ordering of Canvases |
|
260 |
+
| `hidden` | Annotations, etc. | Not rendered by default |
|
261 |
+
|
262 |
+
### Viewing Directions
|
263 |
+
- `left-to-right` (default)
|
264 |
+
- `right-to-left`
|
265 |
+
- `top-to-bottom`
|
266 |
+
- `bottom-to-top`
|
267 |
+
|
268 |
+
---
|
269 |
+
|
270 |
+
## Practical Integration Examples
|
271 |
+
|
272 |
+
## Practical Integration Examples
|
273 |
+
|
274 |
+
### Image API + Presentation API Workflow
|
275 |
+
1. **Presentation API** provides structure and metadata via Manifests
|
276 |
+
2. **Image API** delivers actual image content with manipulation capabilities
|
277 |
+
3. **Annotations** link Image API resources to Canvas positions
|
278 |
+
|
279 |
+
```json
|
280 |
+
{
|
281 |
+
"id": "https://example.org/canvas/page1",
|
282 |
+
"type": "Canvas",
|
283 |
+
"height": 1000,
|
284 |
+
"width": 750,
|
285 |
+
"items": [{
|
286 |
+
"id": "https://example.org/annopage/page1",
|
287 |
+
"type": "AnnotationPage",
|
288 |
+
"items": [{
|
289 |
+
"id": "https://example.org/annotation/page1-image",
|
290 |
+
"type": "Annotation",
|
291 |
+
"motivation": "painting",
|
292 |
+
"body": {
|
293 |
+
"id": "https://example.org/iiif/page1/full/max/0/default.jpg",
|
294 |
+
"type": "Image",
|
295 |
+
"format": "image/jpeg",
|
296 |
+
"service": [{
|
297 |
+
"id": "https://example.org/iiif/page1",
|
298 |
+
"type": "ImageService3",
|
299 |
+
"profile": "level2"
|
300 |
+
}]
|
301 |
+
},
|
302 |
+
"target": "https://example.org/canvas/page1"
|
303 |
+
}]
|
304 |
+
}]
|
305 |
+
}
|
306 |
+
```
|
307 |
+
|
308 |
+
### Image API Examples
|
309 |
+
|
310 |
+
### General Examples
|
311 |
+
```
|
312 |
+
# Full image at maximum size, default quality, JPEG format
|
313 |
+
https://example.org/image-service/abcd1234/full/max/0/default.jpg
|
314 |
+
|
315 |
+
# Square region, scaled to 200px width
|
316 |
+
https://example.org/image-service/abcd1234/square/200,/0/default.jpg
|
317 |
+
|
318 |
+
# Specific region by pixels, 50% scale, 90° rotation
|
319 |
+
https://example.org/image-service/abcd1234/125,15,120,140/pct:50/90/color.png
|
320 |
+
|
321 |
+
# Region by percentage, best fit 300x200
|
322 |
+
https://example.org/image-service/abcd1234/pct:25,25,50,50/!300,200/0/gray.jpg
|
323 |
+
|
324 |
+
# Image information document
|
325 |
+
https://example.org/image-service/abcd1234/info.json
|
326 |
+
```
|
327 |
+
|
328 |
+
### Riksarkivet (Swedish National Archives) Examples
|
329 |
+
|
330 |
+
**IIIF Image API 3.0:**
|
331 |
+
```
|
332 |
+
# Base URL patterns
|
333 |
+
https://lbiiif.riksarkivet.se/{image-id}/{region}/{size}/{rotation}/{quality}.jpg
|
334 |
+
https://lbiiif.riksarkivet.se/v3/{image-id}/{region}/{size}/{rotation}/{quality}.jpg
|
335 |
+
|
336 |
+
# Full image examples
|
337 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/max/0/default.jpg
|
338 |
+
|
339 |
+
# Square crop
|
340 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/square/max/0/default.jpg
|
341 |
+
|
342 |
+
# Region by pixels (x=300, y=300, width=100, height=100)
|
343 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/300,300,100,100/max/0/default.jpg
|
344 |
+
|
345 |
+
# Scale to fixed width (300px)
|
346 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/300,/0/default.jpg
|
347 |
+
|
348 |
+
# Scale to fixed height (500px)
|
349 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/,500/0/default.jpg
|
350 |
+
|
351 |
+
# Scale to exact dimensions (may distort aspect ratio)
|
352 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/500,300/0/default.jpg
|
353 |
+
|
354 |
+
# 90-degree clockwise rotation
|
355 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/max/90/default.jpg
|
356 |
+
|
357 |
+
# 90-degree rotation with horizontal flip
|
358 |
+
https://lbiiif.riksarkivet.se/arkis!R0001216_00005/full/max/!90/default.jpg
|
359 |
+
```
|
360 |
+
|
361 |
+
**IIIF Presentation API:**
|
362 |
+
```
|
363 |
+
# Manifest for a specific resource
|
364 |
+
https://lbiiif.riksarkivet.se/{identifier}/manifest
|
365 |
+
|
366 |
+
# Example manifest
|
367 |
+
https://lbiiif.riksarkivet.se/arkis!R0000480/manifest
|
368 |
+
|
369 |
+
# Collections (hierarchical organization)
|
370 |
+
https://lbiiif.riksarkivet.se/collection/riksarkivet
|
371 |
+
https://lbiiif.riksarkivet.se/collection/amnesomraden # Subject areas
|
372 |
+
https://lbiiif.riksarkivet.se/collection/tid # Time periods
|
373 |
+
|
374 |
+
# Collection by archive unit PID
|
375 |
+
https://lbiiif.riksarkivet.se/collection/arkiv/2Yz2ClKdn2VMeUXQcoZOO6
|
376 |
+
```
|
377 |
+
|
378 |
+
**IIIF Content Search:**
|
379 |
+
```
|
380 |
+
# Search within a volume
|
381 |
+
https://lbiiif.riksarkivet.se/search/arkis!40008511?q=kaffe
|
382 |
+
https://lbiiif.riksarkivet.se/search/arkis!A0068583?q=juveler
|
383 |
+
```
|
384 |
+
|
385 |
+
### Universal Examples (Any IIIF Server)
|
386 |
+
|
387 |
+
## Key Implementation Notes
|
388 |
+
|
389 |
+
- Parameters must be in exact order: region/size/rotation/quality.format
|
390 |
+
- All special characters in identifiers must be URI encoded
|
391 |
+
- Operations are applied in parameter order: extract region → scale → rotate → adjust quality → convert format
|
392 |
+
- Servers SHOULD support CORS on image responses
|
393 |
+
- If region extends beyond image bounds, crop at edges rather than adding empty space
|
394 |
+
- Zero-dimension regions should return 400 Bad Request
|
395 |
+
|
396 |
+
## Error Handling and Rate Limiting
|
397 |
+
|
398 |
+
Common HTTP status codes:
|
399 |
+
- `400 Bad Request` - Invalid parameters
|
400 |
+
- `403 Forbidden` - Missing rights marking or access denied
|
401 |
+
- `404 Not Found` - Image/resource not found
|
402 |
+
- `429 Too Many Requests` - Rate limit exceeded (check X-RateLimit-* headers)
|
403 |
+
- `501 Not Implemented` - Feature not supported
|
404 |
+
|
405 |
+
## CORS Configuration
|
406 |
+
|
407 |
+
For external applications, configure CORS headers:
|
408 |
+
```
|
409 |
+
# Request header
|
410 |
+
Origin: https://yourdomain.com
|
411 |
+
|
412 |
+
# Response header
|
413 |
+
Access-Control-Allow-Origin: https://yourdomain.com
|
414 |
+
```
|
415 |
+
|
416 |
+
**Reverse Proxy Setup (recommended for external services):**
|
417 |
+
|
418 |
+
Apache HTTP Server:
|
419 |
+
```apache
|
420 |
+
ProxyPass /iiif/ https://lbiiif.riksarkivet.se/
|
421 |
+
ProxyPassReverse /iiif/ https://lbiiif.riksarkivet.se/
|
422 |
+
Header always set Access-Control-Allow-Origin "*"
|
423 |
+
```
|
424 |
+
|
425 |
+
Nginx:
|
426 |
+
```nginx
|
427 |
+
location /iiif/ {
|
428 |
+
proxy_pass https://lbiiif.riksarkivet.se/;
|
429 |
+
add_header Access-Control-Allow-Origin "*";
|
430 |
+
}
|
431 |
+
```
|
432 |
+
|
433 |
+
## Programming Examples
|
434 |
+
|
435 |
+
### Python: Working with IIIF Manifests and Images
|
436 |
+
```python
|
437 |
+
import requests
|
438 |
+
import json
|
439 |
+
|
440 |
+
# Fetch and parse a IIIF Manifest
|
441 |
+
def get_manifest(manifest_url):
|
442 |
+
response = requests.get(manifest_url)
|
443 |
+
return response.json()
|
444 |
+
|
445 |
+
# Extract all image URLs from a manifest
|
446 |
+
def extract_image_urls(manifest):
|
447 |
+
image_urls = []
|
448 |
+
for canvas in manifest.get('items', []):
|
449 |
+
for annotation_page in canvas.get('items', []):
|
450 |
+
for annotation in annotation_page.get('items', []):
|
451 |
+
if annotation.get('motivation') == 'painting':
|
452 |
+
body = annotation.get('body', {})
|
453 |
+
if body.get('type') == 'Image':
|
454 |
+
image_urls.append(body.get('id'))
|
455 |
+
return image_urls
|
456 |
+
|
457 |
+
# Get image service base URL from image URL
|
458 |
+
def get_image_service_url(image_url):
|
459 |
+
# Remove the Image API parameters to get base service URL
|
460 |
+
# e.g., https://example.org/iiif/img1/full/max/0/default.jpg
|
461 |
+
# becomes https://example.org/iiif/img1
|
462 |
+
parts = image_url.split('/')
|
463 |
+
return '/'.join(parts[:-4]) # Remove /region/size/rotation/quality.format
|
464 |
+
|
465 |
+
# Generate thumbnail URL using Image API
|
466 |
+
def create_thumbnail_url(image_url, width=150, height=150):
|
467 |
+
service_url = get_image_service_url(image_url)
|
468 |
+
return f"{service_url}/full/!{width},{height}/0/default.jpg"
|
469 |
+
|
470 |
+
# Example usage
|
471 |
+
manifest_url = "https://lbiiif.riksarkivet.se/arkis!R0000480/manifest"
|
472 |
+
manifest = get_manifest(manifest_url)
|
473 |
+
images = extract_image_urls(manifest)
|
474 |
+
|
475 |
+
for img_url in images:
|
476 |
+
thumb_url = create_thumbnail_url(img_url)
|
477 |
+
print(f"Original: {img_url}")
|
478 |
+
print(f"Thumbnail: {thumb_url}")
|
479 |
+
```
|
480 |
+
|
481 |
+
### Python: Download Images from Riksarkivet Collection
|
482 |
+
```python
|
483 |
+
import requests
|
484 |
+
import sys
|
485 |
+
import json
|
486 |
+
import zipfile
|
487 |
+
import re
|
488 |
+
import os
|
489 |
+
|
490 |
+
URL_BASE = 'https://lbiiif.riksarkivet.se/collection/arkiv/'
|
491 |
+
|
492 |
+
def process_collection(collection, zip_file):
|
493 |
+
for item in collection.get('items', []):
|
494 |
+
res = requests.get(item.get('id'))
|
495 |
+
if res.status_code == 200:
|
496 |
+
item_json = res.json()
|
497 |
+
if item.get('type') == 'Collection':
|
498 |
+
process_collection(item_json, zip_file)
|
499 |
+
else:
|
500 |
+
process_manifest(item_json, zip_file)
|
501 |
+
|
502 |
+
def process_manifest(manifest, zip_file):
|
503 |
+
for canvas in manifest.get('items', []):
|
504 |
+
for annotation_page in canvas.get('items', []):
|
505 |
+
for annotation in annotation_page.get('items', []):
|
506 |
+
image_url = annotation.get('body', {}).get('id')
|
507 |
+
if image_url:
|
508 |
+
regex = re.compile('.*\!(.*)\/full.*')
|
509 |
+
result = regex.match(image_url)
|
510 |
+
if result:
|
511 |
+
image_id = result.group(1)
|
512 |
+
try:
|
513 |
+
file_name = f'{image_id}.jpg'
|
514 |
+
print(f'Processing {file_name}')
|
515 |
+
download_file(image_url, file_name)
|
516 |
+
zip_file.write(file_name, file_name)
|
517 |
+
os.remove(file_name)
|
518 |
+
except Exception as e:
|
519 |
+
print(e)
|
520 |
+
|
521 |
+
def download_file(url, file_name):
|
522 |
+
with requests.get(url, stream=True) as r:
|
523 |
+
r.raise_for_status()
|
524 |
+
with open(file_name, 'wb') as f:
|
525 |
+
for chunk in r.iter_content(chunk_size=8192):
|
526 |
+
f.write(chunk)
|
527 |
+
|
528 |
+
def main():
|
529 |
+
if len(sys.argv) > 1:
|
530 |
+
pid = sys.argv[1]
|
531 |
+
res = requests.get(f'{URL_BASE}{pid}')
|
532 |
+
if res.status_code == 200:
|
533 |
+
collection = res.json()
|
534 |
+
with zipfile.ZipFile(f'{pid}.zip', 'w') as zip_file:
|
535 |
+
process_collection(collection, zip_file)
|
536 |
+
else:
|
537 |
+
print('Usage: download.py <pid>')
|
538 |
+
|
539 |
+
if __name__ == "__main__":
|
540 |
+
main()
|
541 |
+
```
|
542 |
+
|
543 |
+
### JavaScript: IIIF Viewer Integration
|
544 |
+
```javascript
|
545 |
+
// Universal Viewer integration
|
546 |
+
const manifestUri = 'https://lbiiif.riksarkivet.se/arkis!R0000480/manifest';
|
547 |
+
const uv = new UV.createUV('#uv-container', {
|
548 |
+
manifestUri: manifestUri,
|
549 |
+
configUri: '/uv-config.json'
|
550 |
+
});
|
551 |
+
|
552 |
+
// Mirador viewer integration
|
553 |
+
const mirador = Mirador.viewer({
|
554 |
+
id: 'mirador-container',
|
555 |
+
windows: [{
|
556 |
+
manifestId: manifestUri,
|
557 |
+
canvasId: 'https://lbiiif.riksarkivet.se/arkis!R0000480/canvas/1'
|
558 |
+
}]
|
559 |
+
});
|
560 |
+
|
561 |
+
// OpenSeadragon with IIIF Image service
|
562 |
+
const viewer = OpenSeadragon({
|
563 |
+
id: 'osd-container',
|
564 |
+
tileSources: {
|
565 |
+
'@context': 'http://iiif.io/api/image/3/context.json',
|
566 |
+
'@id': 'https://lbiiif.riksarkivet.se/arkis!R0000480_00001',
|
567 |
+
'profile': 'level1'
|
568 |
+
}
|
569 |
+
});
|
570 |
+
|
571 |
+
// Fetch manifest and display metadata
|
572 |
+
async function displayManifest(manifestUrl) {
|
573 |
+
const response = await fetch(manifestUrl);
|
574 |
+
const manifest = await response.json();
|
575 |
+
|
576 |
+
// Display basic info
|
577 |
+
const title = manifest.label?.en?.[0] || manifest.label?.sv?.[0] || 'Untitled';
|
578 |
+
const summary = manifest.summary?.en?.[0] || manifest.summary?.sv?.[0] || '';
|
579 |
+
|
580 |
+
document.getElementById('title').textContent = title;
|
581 |
+
document.getElementById('summary').textContent = summary;
|
582 |
+
|
583 |
+
// Display metadata
|
584 |
+
const metadataContainer = document.getElementById('metadata');
|
585 |
+
manifest.metadata?.forEach(item => {
|
586 |
+
const label = item.label?.en?.[0] || item.label?.sv?.[0] || '';
|
587 |
+
const value = item.value?.en?.[0] || item.value?.sv?.[0] || '';
|
588 |
+
|
589 |
+
const div = document.createElement('div');
|
590 |
+
div.innerHTML = `<strong>${label}:</strong> ${value}`;
|
591 |
+
metadataContainer.appendChild(div);
|
592 |
+
});
|
593 |
+
}
|
594 |
+
```
|
595 |
+
|
596 |
+
### Finding Image IDs from Archive Units
|
597 |
+
1. Get archive unit PID from search interface
|
598 |
+
2. Fetch collection data: `https://lbiiif.riksarkivet.se/collection/arkiv/{pid}`
|
599 |
+
3. Extract manifest URLs from `items` array
|
600 |
+
4. Parse image IDs from manifest image URLs
|
601 |
+
|
602 |
+
### IIIF Presentation API Structure
|
603 |
+
|
604 |
+
**Collection Response Example:**
|
605 |
+
```json
|
606 |
+
{
|
607 |
+
"id": "https://lbiiif.riksarkivet.se/collection/arkiv/2Yz2ClKdn2VMeUXQcoZOO6",
|
608 |
+
"type": "Collection",
|
609 |
+
"label": { "sv": ["1 (1654-1721) - Handlingar rörande förhandlingar..."] },
|
610 |
+
"summary": { "sv": ["Referenskod: SE/RA/2113/2113.2/1"] },
|
611 |
+
"items": [
|
612 |
+
{
|
613 |
+
"id": "https://lbiiif.riksarkivet.se/arkis!R0000480/manifest",
|
614 |
+
"type": "Manifest",
|
615 |
+
"label": { "sv": ["1 (1654-1721) - R0000480 - Handlingar..."] }
|
616 |
+
}
|
617 |
+
]
|
618 |
+
}
|
619 |
+
```
|
620 |
+
|
621 |
+
**Hierarchy:**
|
622 |
+
- **Collection** → Contains other Collections or Manifests
|
623 |
+
- **Manifest** → Contains Canvases (individual pages/images)
|
624 |
+
- **Canvas** → Contains image annotations with Image API URLs
|
625 |
+
|
626 |
+
## Common Use Cases
|
627 |
+
|
628 |
+
### Image API
|
629 |
+
- **Thumbnails** - Quick generation of preview images at specific sizes
|
630 |
+
- **Deep zoom viewers** - Requesting tiles and regions for interactive viewing
|
631 |
+
- **Responsive images** - Serving appropriate sizes for different devices
|
632 |
+
- **Image analysis** - Extracting specific regions for processing
|
633 |
+
- **Print quality** - High-resolution downloads with rotation/cropping
|
634 |
+
|
635 |
+
### Presentation API
|
636 |
+
- **Digital libraries** - Organizing books, manuscripts, and documents
|
637 |
+
- **Museum collections** - Presenting artworks with metadata and context
|
638 |
+
- **Archives** - Hierarchical organization of historical materials
|
639 |
+
- **Educational platforms** - Structured learning materials with annotations
|
640 |
+
- **Cultural heritage** - Multi-language, multi-institutional content sharing
|
641 |
+
|
642 |
+
### Combined Workflows
|
643 |
+
- **Reading room interfaces** - Full manuscripts with page-turning and zoom
|
644 |
+
- **Annotation tools** - Transcription and commentary systems
|
645 |
+
- **Comparative viewing** - Side-by-side analysis of similar materials
|
646 |
+
- **Mobile apps** - Responsive cultural heritage exploration
|
647 |
+
- **Research platforms** - Advanced search and analysis tools
|
648 |
+
|
649 |
+
## Implementation Notes
|
650 |
+
|
651 |
+
### Content Delivery Best Practices
|
652 |
+
- Use Image API for dynamic image manipulation and delivery
|
653 |
+
- Use Presentation API for metadata, structure, and viewing instructions
|
654 |
+
- Combine both APIs for complete digital object presentation
|
655 |
+
- Implement proper caching strategies for performance
|
656 |
+
- Consider CDN deployment for global access
|
657 |
+
|
658 |
+
### Client Application Patterns
|
659 |
+
1. **Parse Manifest** → Extract structure and metadata
|
660 |
+
2. **Render Canvas** → Display individual views/pages
|
661 |
+
3. **Load Images** → Use Image API services for content
|
662 |
+
4. **Handle Annotations** → Process transcriptions, translations, comments
|
663 |
+
5. **Navigate Structure** → Use Ranges for table of contents
|
664 |
+
6. **Apply Behaviors** → Follow presentation hints (paging, auto-advance, etc.)
|
665 |
+
|
666 |
+
### Data Flow
|
667 |
+
```
|
668 |
+
Collection → Manifest → Canvas → Annotation → Image Service
|
669 |
+
↓ ↓ ↓ ↓ ↓
|
670 |
+
Hierarchy Metadata Viewport Association Pixels
|
671 |
+
```
|
672 |
+
|
673 |
+
## Implementation Variations
|
674 |
+
|
675 |
+
### Riksarkivet (Swedish National Archives) Specifics
|
676 |
+
**Technical Implementation:**
|
677 |
+
- **Compliance Level**: Image API Level 1 (basic features)
|
678 |
+
- **Supported Formats**: JPEG only (`.jpg`)
|
679 |
+
- **Supported Quality**: `default` only
|
680 |
+
- **Version Support**: Both IIIF 2.0 and 3.0 APIs
|
681 |
+
- **Content Types**:
|
682 |
+
- Images: `content-type: image/jpeg`
|
683 |
+
- Manifests: `content-type: application/json`
|
684 |
+
- **Access Rights**: Public digitized archives older than 110 years
|
685 |
+
- **Rate Limiting**: Enforced with `X-RateLimit-*` headers
|
686 |
+
|
687 |
+
**Content Organization:**
|
688 |
+
- Collections organized by subject (`amnesomraden`) and time (`tid`)
|
689 |
+
- Archive units identified by persistent IDs (PIDs)
|
690 |
+
- Manifests correspond to volumes or individual items
|
691 |
+
- Search integration with full-text OCR content
|
692 |
+
|
693 |
+
**API Endpoints:**
|
694 |
+
- Image API: `https://lbiiif.riksarkivet.se/`
|
695 |
+
- Collections: `https://lbiiif.riksarkivet.se/collection/`
|
696 |
+
- Search: `https://lbiiif.riksarkivet.se/search/`
|
697 |
+
|
698 |
+
### General IIIF Implementation Patterns
|
699 |
+
|
700 |
+
**Compliance Levels (Image API):**
|
701 |
+
- **Level 0**: Static images with limited manipulation
|
702 |
+
- **Level 1**: Basic resize, rotation, quality options
|
703 |
+
- **Level 2**: Full specification support with advanced features
|
704 |
+
|
705 |
+
**Common Institution Patterns:**
|
706 |
+
- **Museums**: Focus on high-quality images with rich metadata
|
707 |
+
- **Libraries**: Emphasis on text materials with OCR and search
|
708 |
+
- **Archives**: Hierarchical organization with finding aids
|
709 |
+
- **Universities**: Research-focused with annotation tools
|
710 |
+
|
711 |
+
**Supported IIIF APIs (Typical Implementations):**
|
712 |
+
- ✅ **Image API 3.0/2.0** - Core image delivery (universal)
|
713 |
+
- ✅ **Presentation API 3.0** - Metadata and structure (most institutions)
|
714 |
+
- ✅ **Content Search API 1.0** - Full-text search (text-heavy collections)
|
715 |
+
- ⚠️ **Authentication API 1.0** - Access control (restricted content)
|
716 |
+
- ⚠️ **Change Discovery API 1.0** - Update notifications (large institutions)
|
717 |
+
|
718 |
+
### Server Technology Stacks
|
719 |
+
|
720 |
+
**Popular IIIF Server Software:**
|
721 |
+
- **Cantaloupe** - Java-based image server (Image API)
|
722 |
+
- **IIPImage** - C++ high-performance server
|
723 |
+
- **Loris** - Python image server
|
724 |
+
- **RIIIF** - Ruby implementation
|
725 |
+
- **Omeka S** - Content management with IIIF support
|
726 |
+
- **Samvera/Hyrax** - Digital repository platform
|
727 |
+
- **DSpace** - Institutional repository with IIIF modules
|
728 |
+
|
729 |
+
**Cloud Solutions:**
|
730 |
+
- **IIIF Hosting** - Managed IIIF services
|
731 |
+
- **AWS/Azure/GCP** - Serverless IIIF implementations
|
732 |
+
- **ContentDM** - OCLC's hosted digital collections platform
|
733 |
+
|
734 |
+
## Integration with Viewers
|
735 |
+
|
736 |
+
### Popular IIIF-Compatible Viewers
|
737 |
+
|
738 |
+
**Full-Featured Viewers:**
|
739 |
+
- **Universal Viewer** - Complete presentation with navigation and metadata
|
740 |
+
- **Mirador** - Advanced viewer with workspace and comparison features
|
741 |
+
- **Tify** - Vue.js-based viewer for modern web applications
|
742 |
+
|
743 |
+
**Specialized Viewers:**
|
744 |
+
- **OpenSeadragon** - High-performance pan/zoom for images
|
745 |
+
- **Leaflet-IIIF** - Map-style tile viewer for large images
|
746 |
+
- **Annona** - Lightweight annotation-focused viewer
|
747 |
+
|
748 |
+
**Implementation Examples:**
|
749 |
+
```javascript
|
750 |
+
// Universal Viewer (comprehensive)
|
751 |
+
const manifestUri = 'https://lbiiif.riksarkivet.se/arkis!R0000480/manifest';
|
752 |
+
const uv = new UV.createUV('#uv', { manifestUri: manifestUri });
|
753 |
+
|
754 |
+
// Mirador (research-focused)
|
755 |
+
const mirador = Mirador.viewer({
|
756 |
+
id: 'mirador',
|
757 |
+
windows: [{ manifestId: manifestUri }],
|
758 |
+
workspaceControlPanel: { enabled: true }
|
759 |
+
});
|
760 |
+
|
761 |
+
// OpenSeadragon (image-focused)
|
762 |
+
const viewer = OpenSeadragon({
|
763 |
+
id: 'osd',
|
764 |
+
tileSources: 'https://example.org/iiif/image1/info.json'
|
765 |
+
});
|
766 |
+
```
|
767 |
+
|
768 |
+
### Mobile and Responsive Considerations
|
769 |
+
- Progressive image loading for bandwidth optimization
|
770 |
+
- Touch-friendly zoom and pan interactions
|
771 |
+
- Adaptive metadata display for small screens
|
772 |
+
- Offline capability for downloaded content
|
773 |
+
- Platform-specific apps (iOS/Android) using IIIF APIs
|