2023/01/11
IIIF概説
今回は弊社の栗山が「IIIF」について話しました。 (ブログとしての公開時期が遅れてしまいましたが、実際に調べていたのは2021年秋あたりなのでその時点での情報です)
IIIF(トリプル・アイ・エフ)とは、International Image Interoperability Framework の略。
解説を直訳すると、高品質な属性付きのデジタルオブジェクトをスケーラブルに配布するためのオープンフレームワーク。というものらしいですが、昨今では図書館や美術館のデジタルアーカイブで、IIIF に対応した画像ビューアを使えるようにする仕組みなどに使われています。
下に挙げた 6 つの API が定義されており、これらをまとめて IIIF というフレームワークになります。
JSON-LD とは JSON for Linking Data の略で、情報同士を結合させて表現するための構造化データ、そのシンタックスの一種です。そのようなシンタックスには他に
といったものがあります。
JSON-LD は RDFa や Microformats と違い、記載する場所に制限がないのが特徴で、
Google によって現在使用が推奨されています。
やろうとしていることは RDFa や Microformats と同じで、例えば
というデータ構造は、
だと
これは完全に書き下す形の表現方法です。それ以外にも、URI を記述するだけ、上記
どれぐらい詳しい情報を返すかによりレベルが変わります。
レベル 0
何らかの変更があったことだけを伝えます。
あるオブジェクトが削除された場合には、一覧を見て判断する必要があります。
レベル 1
レベル 2
レベル 2 になると
検索エンジンの URL は
こちらは
検索 API は
Request の送り方は、
また、AutoComplete 用の補助 API も定義されており、先ほどのコードを下のように拡張できます。
これは
ただ、認証の具体的な仕組み自体は定義せず「どういうタイプの認証が必要で、どこをたどればいいか」を記述します。
例えば下記のコードでは、
その他にもログインではなく、利用規約などを踏ませるパターンだと
ここまでで説明した API はどちらかと言えばフレームワークとしての屋台骨であり、一度実装してしまえばそれほど使用頻度の高くないものです。画像を表示したりという用途では、これから説明する残りの二つが主に使用することになります。
クエリパラメータではなくパスセグメントを使って情報を伝えます。というのも画像なので、キャッシュされやすいことを意識してそのようになっています。
ある画像を任意のサイズや回転などで取りたい時に、このようなルールでパスを作成すれば取得できると決められるのがこの API の肝です。
画像自体は、
メタ情報は、
という構文でリクエストします。
これは画像処理の適用順序に合わせた順番になっています。
これらのパラメータを構文の中に含めて任意の画像をリクエストすることができます。
画像のメタ情報は、
ずらっと画像情報が並んでいますが、
タイル化された情報も記述できます:
というのも、例えばオリジナルの画像サイズが大きいため、サーバー側で分割した状態で保管されており、分割リクエストした上で、クライアント側で画像を繋げて一枚の画像として閲覧できるようにする、や、ズームインターフェイスを使って一部だけを拡大表示する仕組みなどが想定されているからです。
と記述されているのは、サーバー側で幅高さが 1/1, 1/2, 1/4, 1/8, 1/16 の形でそれぞれ分割されたものが用意されているということを示しています。
ユーザーはこの情報を見て、どのように画像を見せるかを考えてリクエストを選択することができます。
この規格は、
これらを目的としており、図のような階層が組み合わさった JSON で表現されます。
駆け足になりましたが、以上が「IIIF」の概要です。
これを使うことで、汎用的なビューアーを作成することができます。
以下は実際に IIIF に基づいて実装されたものです。良かったら参考に見てみてください。
IIIF(トリプル・アイ・エフ)とは、International Image Interoperability Framework の略。
解説を直訳すると、高品質な属性付きのデジタルオブジェクトをスケーラブルに配布するためのオープンフレームワーク。というものらしいですが、昨今では図書館や美術館のデジタルアーカイブで、IIIF に対応した画像ビューアを使えるようにする仕組みなどに使われています。
下に挙げた 6 つの API が定義されており、これらをまとめて IIIF というフレームワークになります。
- Image API
- Presentation API
- Authentication API
- Content Search API
- Change Discovery API
- Content State API (draft)
JSON-LD
IIIF では JSON-LD に準拠した構造のレスポンスが返ってきます。JSON-LD とは JSON for Linking Data の略で、情報同士を結合させて表現するための構造化データ、そのシンタックスの一種です。そのようなシンタックスには他に
- Microformats
- RDFa
といったものがあります。
JSON-LD は RDFa や Microformats と違い、記載する場所に制限がないのが特徴で、
Google によって現在使用が推奨されています。
やろうとしていることは RDFa や Microformats と同じで、例えば
{
"@context": "http://schema.org/",
"@type": "Product",
...
}
http://schema.org
で定義されている Product
という型のものを表現しますが、後続する属性はその型定義によって変わります。
{
"@context": "https://json-ld.org/contexts/person.jsonld",
"@id": "http://dbpedia.org/resource/John_Lennon",
"name": "John Lennon",
"born": "1940-10-09",
"spouse": "http://dbpedia.org/resource/Cynthia_Lennon"
}
@context
に @type
相当の情報まで含まれているので @type
は省略し、それ以外の属性はその @context
で定義されている、という形式になります。Content State API
後で説明する Presentation API のリソース、もしくはリソースの一部を、コンパクトな表現で参照するための規格です。{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://example.org/Annotation-server/bookmarks/b1",
"type": "Annotation",
"motivation": ["contentState"],
"target": {
"id": "https://example.org/iiif/item1/manifest",
"type": "Manifest"
}
}
target
部分だけ、などの表現方法があります。State
は、REST(Representational State Transfer)でいうところの Resource State
にあたります。Change Discovery API
名前の通り、変更された記述を見つけるための API です。どれぐらい詳しい情報を返すかによりレベルが変わります。
レベル 0
{
"type": "Update",
"object": {
"id": "https://example.org/iiif/1/manifest",
"type": "Manifest"
}
}
あるオブジェクトが削除された場合には、一覧を見て判断する必要があります。
レベル 1
{
"type": "Update",
"object": {
"id": "https://example.org/iiif/1/manifest",
"type": "Manifest"
},
"endTime": "2017-09-20T00:00:00Z"
}
endTime
という属性が増えていますが、ここには最終更新日、もしくは新規作成日が入ります。ここまではリソースの存在を別の手段で知っていて、その変更点を知る、というだけの情報です。レベル 2
{
"type": "Create",
"object": {
"id": "https://example.org/iiif/1/manifest",
"type": "Manifest"
},
"endTime": "2017-09-20T00:00:00Z"
}
type
のところに Create
, Delete
, Move
といった状態が見られるようになります。レベルが上がるほど、参照する側としては便利になりますが、サーバー側の実装としては手間がかかりそうな感じです。Content Search API
検索内容にコンテンツについた注釈からリストを取得する API です。検索エンジンの URL は
service
という LD を使って定義し、そのリソースによって検索されるコンテンツの範囲を決めます。こちらは
service
記述の例になりますが、
{
// ... the resource that the search service is associated with ...
"service": {
"@context": "http://iiif.io/api/search/1/context.json",
"@id": "http://example.org/services/identifier/search",
"profile": "http://iiif.io/api/search/1/search"
}
}
@content
, profile
を上記で固定し、 @id
が実際の検索 API URL を指しています。Request の送り方は、
q=
がクエリ文字列、さらに date=
, user=
のようなリクエストも可能です。いずれも空白区切りにしなければなりません。検索できるパラメータについてはこちらをご覧ください。また、AutoComplete 用の補助 API も定義されており、先ほどのコードを下のように拡張できます。
{
// Resource that the services are associated with ...
"service": {
"@context": "http://iiif.io/api/search/1/context.json",
"@id": "http://example.org/services/identifier/search",
"profile": "http://iiif.io/api/search/1/search",
"service": {
"@id": "http://example.org/services/identifier/autocomplete",
"profile": "http://iiif.io/api/search/1/autocomplete"
}
}
}
q=
に「bir」という文字列を入れてリクエストを送った場合ですが、search:TermList
というレスポンスで、それぞれ「bir」を含む検索結果が返ってきています。
{
"@context": "http://iiif.io/api/search/1/context.json",
"@id": "http://example.org/service/identifier/autocomplete?q=bir&motivation=painting",
"@type": "search:TermList",
"ignored": ["user"],
"terms": [
{
"match": "bird",
"url": "http://example.org/service/identifier/search?motivation=painting&q=bird",
"count": 15
},
{
"match": "biro",
"url": "http://example.org/service/identifier/search?motivation=painting&q=biro",
"count": 3
},
{
"match": "birth",
"url": "http://example.org/service/identifier/search?motivation=painting&q=birth",
"count": 9
},
{
"match": "birthday",
"url": "http://example.org/service/identifier/search?motivation=painting&q=birthday",
"count": 21
}
]
}
Authentication API
リソースへのアクセスに対して、認証が必要な形を提供するための規格です。ただ、認証の具体的な仕組み自体は定義せず「どういうタイプの認証が必要で、どこをたどればいいか」を記述します。
例えば下記のコードでは、
@id
でログイン用の URL が示され、 profile
で対話ログインを示しています。
{
// ...
"service" : {
"@context": "http://iiif.io/api/auth/1/context.json",
"@id": "https://authentication.example.org/login",
"profile": "http://iiif.io/api/auth/1/login",
"label": "Login to Example Institution",
"header": "Please Log In",
"description": "Example Institution requires that you log in with your example account to view this content.",
"confirmLabel": "Login",
"failureHeader": "Authentication Failed",
"failureDescription": "<a href=\"http://example.org/policy\">Access Policy</a>",
"service": [
// Access token and Logout services ...
]
}
}
profile
に http://iiif.io/api/auth/1/clickthrough
を記述することで、対話なしの踏み台を作成することが可能です。ここまでで説明した API はどちらかと言えばフレームワークとしての屋台骨であり、一度実装してしまえばそれほど使用頻度の高くないものです。画像を表示したりという用途では、これから説明する残りの二つが主に使用することになります。
Image API
画像と、それに付随するメタ情報をリクエストするための API です。クエリパラメータではなくパスセグメントを使って情報を伝えます。というのも画像なので、キャッシュされやすいことを意識してそのようになっています。
ある画像を任意のサイズや回転などで取りたい時に、このようなルールでパスを作成すれば取得できると決められるのがこの API の肝です。
画像自体は、
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
{scheme}://{server}{/prefix}/{identifier}/info.json
これは画像処理の適用順序に合わせた順番になっています。
Request | 型 |
---|---|
{region} | full ・・・画像全体。square ・・・元画像の短辺合わせの矩形画像を返します。長辺位置はサーバー側が自由に決めるが、一般的には中央がデフォルト。x,y,w,h ・・・具体的な位置指定が可能。画像左上を 0,0とし、w,h で幅と高さを指定して画像を切り抜ける。単位はpx。pct:x,y,w,h ・・・パーセントによる指定。例えば x に 50 を指定すると元画像の大きさから 50% な位置を指定という意味。 |
{size} | max ・・・別情報の maxWidth , maxHeigt , maxArea で示される最大サイズに。w, ,h ・・・幅が指定値になるよう、縦横比を維持して拡縮。pct:n ・・・n パーセントにスケーリングされる。100を超えてはいけない。 |
{rotation} | n ・・・ 0 から 360 までの時計回りの回転角度。 !n ・・・回転が適用される前に垂直軸に基づいて反転される。 |
{quality} | color ・・・フルカラー。gray ・・・グレースケール。bitonal ・・・二値画像。白か黒。 default ・・・サーバー任せ。 |
{format} | 拡張子。jpg , tif , png , gif , jp2 , pdf , webp などが指定できる。サポートされていないフォーマットがリクエストされた場合は 400 を返す。 |
※ここで紹介したパラメータはごく一部です。全てをご覧になりたい方はこちらのドキュメントをご覧ください。
画像のメタ情報は、
applicaton/ld+json
で JSON-LD 形式で返ってきます(サーバーがサポートしてなければ application/json
でもOK)。
{
"@context": "http://iiif.io/api/image/3/context.json",
"id": "https://example.org/image-service/abcd1234/1E34750D-38DB-4825-A38A-B60A345E591C",
"type": "ImageService3",
"protocol": "http://iiif.io/api/image",
"profile": "level2",
"width": 6000,
"height": 4000,
"maxHeight": 2000,
"maxWidth": 3000,
"maxArea": 4000000
}
@context
, type
, protocol
は固定。 id
には {identifier}
までを含めた URI が入ります(末尾 /
無し)。width
と height
がオリジナルの画像サイズ(px)で、maxWidth
, maxHeight
はそれ以上のサイズではリクエストできないということを表しています。タイル化された情報も記述できます:
{
"@context": "http://iiif.io/api/image/3/context.json",
"id": "https://example.org/image-service/abcd1234/1E34750D-38DB-4825-A38A-B60A345E591C",
"type": "ImageService3",
"protocol": "http://iiif.io/api/image",
"profile": "level2",
"width": 6000,
"height": 4000,
"tiles": [
{ "width": 512, "scaleFactors": [ 1, 2, 4, 8, 16 ] }
]
}
"scaleFactors": [ 1, 2, 4, 8, 16 ]
ユーザーはこの情報を見て、どのように画像を見せるかを考えてリクエストを選択することができます。
Presentation API
仕様書には digitized physical objects とありましたが、つまりモノのコレクションの構造、レイアウト、表現方法などを JSON で記述するための規格です。 デジタイズしたものだけでなく、元々デジタルで作られたもの(bornd-digital object
)も対象にしている様子。この規格は、
- ユーザーに画像、ビデオ、音声その他のモノを表示する。
- ユーザーが複数のビュー、時間軸で(直線的、階層的に)遷移することを可能にする。
- モノ、ビュー、ナビゲーション構造についての情報をユーザーに提供する。
- モノの発行人とユーザーが追加情報を注釈して共有することを可能にする。
これらを目的としており、図のような階層が組み合わさった JSON で表現されます。
Collection
Manifest
title などの属性で compound object の特徴を示すもの。
Canvas
object の一つの見え方を定義するもの。
Range
Annotation Page
Annotation
Content
実際の画像、音声、ビデオ、テキストなど。
Manifest
, Collection
の順序付き集合。Manifest
title などの属性で compound object の特徴を示すもの。
Canvas
object の一つの見え方を定義するもの。
Range
Canvas
が複数ある時の順序付き集合。Annotation Page
Annotation
の順序付き集合。Annotation
Canvas
と Content
をつなげて、かつメタ情報を記述するもの。Content
実際の画像、音声、ビデオ、テキストなど。
駆け足になりましたが、以上が「IIIF」の概要です。
これを使うことで、汎用的なビューアーを作成することができます。
以下は実際に IIIF に基づいて実装されたものです。良かったら参考に見てみてください。