本ページは IIIF Presentation API 3.0 に従って、マニフェストの作り方を解説します。
マニフェストの作り方の大まかな流れは次のとおりです。
キャンバスは IIIF ビューワの表示域を表します。基本的には、メインとなる素材(画像、動画)ごとに 1 つのキャンバスを用意します。1 つのキャンバスに複数の素材を載せることもできます(たとえば、画像と注釈テキスト、動画と字幕テキストなど)。キャンバスに載せる素材のことをアノテーションと呼びます。
ただし、素材(アノテーション)を直接キャンバスに載せていくのではなく、いったんアノテーション・ページと呼ばれるレイヤーを作成し、キャンバスに重ねていく感じになります。
マニフェスト、キャンバス、アノテーション・ページ、アノテーションはすべて、JSON-LD にもとづく JSON オブジェクトとして記述されます。
マニフェストは、IIIF ビューワに読み込ませるための全設定を統括する JSON オブジェクトです。
type を持ち、その値は Manifest です。id を持ち、その値はマニフェスト自身の URI です。
https://example.org/Archive/Record1/manifest.jsonld のようなファイル名でも構いません。URI 自体に意味があるわけではないので、「他とは重複しない識別子」になっていれば十分です。label を持ち、その値は、このマニフェストが指し示すデータ全体のタイトルです。多言語化に対応していますが、必ず { "言語名" : [ "タイトル" ] } の形式で書かなければなりません。items を持ち、その値は各キャンバスの宣言です。{
"type": "Manifest",
"id": "https://example.org/Archive/Record1/manifest",
"label": { "en": [ "Record 1" ], "ja": [ "記録 1" ] },
"items": [
// ここに各キャンバスの宣言が置かれる
]
}
実際には、マニフェストを独立ファイルにすることが多いでしょう。独立ファイル manifest.json を作成した場合は次のようになります。
@context で IIIF のバージョンを宣言しなければなりません。// manifest.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "Manifest",
"id": "https://example.org/Archive/Record1/manifest.json",
"label": { "en": [ "Record 1" ], "ja": [ "記録 1" ] },
"items": [
// ここに各キャンバスの宣言が置かれる
]
}
キャンバスは、IIIF ビューワの表示域を表す JSON オブジェクトです。必要なものは次のとおりですが、特に大事なのは items と annotations です。
type を持ち、その値は Canvas です。id を持ち、その値はキャンバス自身の URI です。label にタイトルを付けましょう。
label は全体のタイトルですが、キャンバスの label は個々のデータのタイトルです。items に、常に表示しておきたいアノテーション・ページの宣言を並べましょう。annotations に、表示・非表示を切り替えたいアノテーション・ページの宣言を並べます。{
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas/1",
"label": { "en": [ "Monologue 1" ], "ja": [ "モノローグ 1" ] },
"items": [
// 常に表示しておきたいアノテーション・ページの宣言が置かれる
],
"annotations": [
// 表示・非表示を切り替えたいアノテーション・ページの宣言が置かれる
]
}
また、必要に応じて次の宣言をします。
width と height でキャンバスのサイズを指定できます(単位はピクセル)。もし指定する場合は width と height を両方とも書かなければなりません。duration で再生時間を指定できます(単位は秒)。{
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas/1",
"label": { "en": [ "Monologue 1" ], "ja": [ "モノローグ 1" ] },
"width": "640",
"height": "480",
"duration": "120",
"items": [
// 常に表示しておきたいアノテーション・ページの宣言が置かれる
],
"annotations": [
// 表示・非表示を切り替えたいアノテーション・ページの宣言が置かれる
]
}
キャンバスを独立ファイルにする場合(たとえば canvas1.json を作成する場合)は、冒頭に @context を付けなければなりません。
{
"type": "Manifest",
"id": "https://example.org/Archive/Record1/manifest",
"label": {"en": ["Record 1" ],"ja": ["記録 1" ] },
"items": [
// ここに各キャンバスの宣言が置かれる
{
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas1.json"
}
]
}
// canvas1.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas1.json",
"label": {"en": ["Monologue 1" ],"ja": ["モノローグ 1" ] },
"width": "640",
"height": "480",
"duration": "120",
"items": [
// 常に表示しておきたいアノテーション・ページの宣言が置かれる
],
"annotations": [
// 表示・非表示を切り替えたいアノテーション・ページの宣言が置かれる
]
}
素材(アノテーション)は直接キャンバスに載せられるのではなく、いったんアノテーション・ページと呼ばれるレイヤーに集積されます。
type を持ち、その値は AnnotationPage です。id を持ち、その値はアノテーション・ページ自身の URI です。items に、各アノテーションの宣言を並べましょう。{
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page/1",
"items": [
// ここに各アノテーションの宣言が置かれる
]
}
たとえば、動画の書き起こし字幕テキスト(page1.json)と翻訳字幕テキスト(page2.json)とを、別のアノテーション・ページとして同時に読み込むことができます。独立ファイルの冒頭には @context を付けなければなりません。
{
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas/1",
"label": { "en": [ "Monologue 1" ], "ja": [ "モノローグ 1" ] },
"items": [
// 常に表示しておきたいアノテーション・ページの宣言が置かれる
],
"annotations": [
// 表示・非表示を切り替えたいアノテーション・ページの宣言が置かれる
{
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page1.json"
},
{
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page2.json"
}
]
}
// 字幕テキスト/page1.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page1.json",
"items": [
// ここに各アノテーションの宣言が置かれる
]
}
// 翻訳テキスト/page2.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page2.json",
"items": [
// ここに各アノテーションの宣言が置かれる
]
}
素材(アノテーション)の JSON オブジェクトは次のようになります。
type を持ち、その値は Annotation です。id を持ち、その値はアノテーション自身の URI です。motivation にいずれかを記述します。
painting。かつ、この値を持つアノテーションは、キャンバスの items(常に表示しておきたいアノテーション・ページ)に含まれなければなりません。supplementing。かつ、この値を持つアノテーションは、キャンバスの annotations(表示・非表示を切り替えたいアノテーション・ページ)に含まれなければなりません。commenting(注釈)など、Web Annotation 勧告で定義された値を使うこともできます。どの値が使えるかは IIIF ビューワによります。body にアノテーションの実体を記述します。target に、このアノテーションを表示させたいキャンバスの id を繰り返します。{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "painting",
"body": {
// アノテーションの実体
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
アノテーションを独立ファイルにする場合(たとえば annotation1.json、annotation2.json を作成する場合)は、冒頭に @context を付けなければなりません。
{
"type": "Canvas",
"id": "https://example.org/Archive/Research2020/canvas/1",
"label": {"en": ["Monologue 1" ],"ja": ["モノローグ 1" ] },
"items": [
// 常に表示しておきたいアノテーション・ページの宣言が置かれる
{
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page/1",
"items": [
// ここに各アノテーションの宣言が置かれる
{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation1.json"
}
]
}
],
"annotations": [
// 表示・非表示を切り替えたいアノテーション・ページの宣言が置かれる
{
"type": "AnnotationPage",
"id": "https://example.org/Archive/Research2020/page/2",
"items": [
// ここに各アノテーションの宣言が置かれる
{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation2.json"
}
]
}
]
}
// annotation1.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation1.json",
"motivation": "painting",
"body": {
// アノテーションの実体
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
// annotation2.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation2.json",
"motivation": "supplementing",
"body": {
// アノテーションの実体
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
繰り返しますが、IIIF ではキャンバスに載せる素材のことをアノテーションと呼びます。アノテーションの実体は画像、動画、音声、注釈テキスト、字幕テキストなど様々です。
アノテーションの実体は body の中に記述されます。外部ファイルを参照する場合も、参照しない場合も、必ず id として URI を持ちます。
画像を参照する場合、
id の URI で画像ファイルを読み込んでも構いませんし、(サーバが対応しているなら)Image API を使用することもできます。type は Image でなければなりません。{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "painting",
"body": {
"id": "https://example.org/Archive/Research2020/content/image1.jpg",
"type": "Image",
"format": "image/jpeg",
"width": "640",
"height": "480"
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "painting",
"body": {
"id": "https://example.org/Archive/Research2020/content/image1/full/640,480/0/default.jpg",
"type": "Image"
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
動画、音声を参照する場合、
id の URI で動画、音声ファイルを読み込みます。type は、動画の場合は Video、音声の場合は Sound でなければなりません。{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "painting",
"body": {
"id": "https://example.org/Archive/Research2020/content/video1.mp4",
"type": "Video",
"format": "audio"
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
動画の字幕テキスト(WebVTT)を参照する場合、
id の URI で字幕テキストファイルを読み込みます。type は Text でなければなりません。{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "painting",
"body": {
"id": "https://example.org/Archive/Research2020/content/tracktext1.vtt",
"type": "Text",
"format": "text/vtt"
},
"target": "https://example.org/Archive/Research2020/canvas/1"
}
画像、動画、音声等への注釈テキストを body に直接埋め込むこともできます。
id として適当な URI を与えます。type に TextualBody を与えます。value にテキストを記述します。このとき、format に text/html を指定すれば HTML を記述することもできます。language で言語を明記することもできます。target で繰り返したキャンバスの URI の後に、
#xywh=0,0,20,30 のように付け足すと、キャンバスの左上を原点として「(0, 0) の座標から、幅 20px、高さ 30px の範囲に対する注釈である」と指定できます。#t=20,25 のように付け足すと、「再生時間 20 秒目から 25 秒目までの範囲の注釈である」と指定できます。#xywh=0,0,20,30&t=20,25 のように両者を合体させることもできます。{
"type": "Annotation",
"id": "https://example.org/Archive/Research2020/annotation/1",
"motivation": "commenting",
"body": {
"id": "https://example.org/Archive/Research2020/content/text1",
"type": "TextualBody",
"format": "text/html",
"language": "en",
"value": "I love <strong>this</strong> portion of the movie!"
},
"target": "https://example.org/Archive/Research2020/canvas/1#xywh=0,0,20,30&t=20,25"
}