IIIF manifestファイルを簡単に作ってみよう

今回は、最低限のIIIF manifestファイルを簡単に作ってみる方法をご用意してみました。経緯等は後回しにして、とりあえずやり方をば。

画像ファイルは、前回記事のやり方でpyramid tiffになっているものとします。拡張子は.tif。 そして、一つの資料ごとに一つのフォルダ(ディレクトリ)にまとめられているものとします。

そこで、まずは以下のようなCSVファイルを作成します。エクセルで作ってCSV UTF-8で保存すれば 大丈夫かと思います。(一応実験済み)

dir,title,license,attribution,viewingDirection,translator,publisher
0040_01,大方廣佛華嚴經 序~巻第二,https://creativecommons.org/licenses/by/4.0/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師
0040_02,大方廣佛華嚴經 巻第三~六,https://creativecommons.org/licenses/by/4.1/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師
0040_03,大方廣佛華嚴經 巻第七~十,https://creativecommons.org/licenses/by/4.2/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師
0040_04,大方廣佛華嚴經 巻第十一~十四,https://creativecommons.org/licenses/by/4.3/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師
0040_05,大方廣佛華嚴經 巻第十五~十七,https://creativecommons.org/licenses/by/4.4/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師
0040_06,大方廣佛華嚴經 巻第十八~二十,https://creativecommons.org/licenses/by/4.5/deed.ja,東京大学総合図書館・SAT大蔵経テキストデータベース研究会,right-to-left,實叉難陀,鉄眼禅師

最も大事なのは、一番左の列です。ここには、画像のフォルダ(ディレクトリ)名を入れておきます。前後の スラッシュは無しです。ここの情報を使って画像フォルダと突合させますので、これは必ず正確に記述してください。 (コピペ推奨です)

その他の内容ですが、まず、一行目は項目を書いて、二行目からコンテンツに対応する各種情報を書いていきます。titleはタイトルを書いておきます。 license (利用条件), attribution (帰属)、viewingDirection(読んでいく方向)あたりは書いておいた方がよいです。特に 右から左にページめくりしていくような物(縦書きの日本語・漢文資料など)はviewingDirectionのところに right-to-leftを書いておくと後々いいことがあります。 licenseは、ライセンス(利用条件)情報が書かれたベージのURLを書いておくことに なっています。なお、項目名については、IIIF Presentation APIで定められているものは英語で書いた方がよいですが、 それ以外の独自の項目名は日本語でつけても今のところはあんまり問題ありません。

繰り返しになりますが、エクセルで作った場合はCSV UTF-8で、そうでなければ普通にUTF-8で保存して いただけば大丈夫かと思います。ここでは仮にファイル名を bib.csv としておきます。

それから、準備として、Python3から画像の大きさを取得できるように、以下のようにモジュールをインストールしておきます。

% sudo pip3 install pillow

さて、次に、以下のスクリプトを回して見ます。

#!/usr/bin/python3
import sys
import glob
import os
import csv
import json
from PIL import Image
base_url = 'https://candra.dhii.jp/iiif/tetsugen/0040/'
#ここ↑はマニフェストが設置されるURLに応じて書き換える
base_image_url = 'https://candra.dhii.jp/iiifimgs/tetsugen/0040/’
#ここ↑はIIIF Image APIのURLに応じて書き換える
all_bib = {}
all_bib2 = {}
bib_title = []
mani_keys = ['dir','title','license','attribution','within','logo', 'description','viewingHint','viewingDirection']
#ここ↑は、IIIF Presentation APIにて、トップレベルで規定される項目を入れておきます。必要に応じて適宜増やしてください。
with open(sys.argv[1], newline='', encoding='utf_8_sig') as csvfile:
  spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
  rn = 0
  for row in spamreader:
    if rn == 0:
      bib_title = row
    else:
      each_bib = {}
      each_bib.update(zip(bib_title,row))
      link_name = row[0]
      all_bib[link_name] = each_bib
    rn = rn + 1;
#print (all_bib)

for key in all_bib.keys():
  each_manifest = {}
  all_meta = []
  file_dir0 = key
  glob_name = key+"/*.tif"
  if os.path.isdir(key):
   list_file_names = glob.glob(glob_name)
   if len(list_file_names) == 0:
     glob_name = key+"/*.ptif"
     list_file_names = glob.glob(glob_name)
   for item in all_bib[key]:
     if item not in mani_keys:
       each_meta  = {}
       item_value = all_bib[key][item]
       each_meta['label'] = item
       each_meta['value'] = item_value
       all_meta.append(each_meta)
   each_manifest['@id'] = base_url+key+'/manifest.json'
   each_manifest['@type'] = 'sc:Manifest'
   each_manifest['@context'] = 'http://iiif.io/api/presentation/2/context.json'
   each_manifest['metadata'] = all_meta
   for mani_key in mani_keys:
     if all_bib[key].get(mani_key):
       if mani_key == 'title':
         each_manifest['label'] = all_bib[key][mani_key]
       elif mani_key != 'dir':
         each_manifest[mani_key] = all_bib[key][mani_key]
   cn = 0
   sequence = {}
   canvases = []
   for file_path in list_file_names:
     service = {}
     resource = {}
     mani_image = {}
     canvas = {}
     file_dir = os.path.split(file_path)[0]
     if os.path.isdir(file_dir):
       cn = cn + 1
       canvas_number = 'p'+str(cn)+'.json'
       image_url_id = base_image_url+file_path
       service['@context'] = 'http://iiif.io/api/image/2/context.json'
       service['@id']  = image_url_id
       service['profile'] = 'http://iiif.io/api/image/2/level1.json'
       img = Image.open(file_path)
       width, height = img.size
       resource['@type'] = 'dctypes:Image'
       resource['format'] = 'image/jpeg'
       resource['width'] = width
       resource['height'] = height
       resource['@id'] = image_url_id+'/full/full/0/default.jpg'
       resource['service'] = service
       mani_image['@type']  = 'oa:Annotation'
       mani_image['motivation']  = 'sc:painting'
       mani_image['resource']  = resource
       mani_image['@id']  = base_url+file_dir+'/annotation/'+canvas_number
       mani_image['on']  = base_url+file_dir+'/canvas/'+canvas_number
       canvas['label'] = 'p. '+str(cn)
       canvas['images'] = []
       canvas['images'].append(mani_image)
       canvas['width'] = width
       canvas['height'] = height
       canvas['@type'] = 'sc:Canvas'
       canvas['@id'] = base_url+file_dir+'/canvas/'+canvas_number
       canvases.append(canvas)
   sequence['@id'] =  base_url+file_dir0+'/sequence/s1.json'
   sequence['@type'] =  'sc:Sequence'
   sequence['label'] =  'Current Page Order'
   sequence['canvases'] = canvases
   each_manifest['sequences'] = []
   each_manifest['sequences'].append(sequence)
   write_file_path = file_dir0+'/manifest.json'
   with open(write_file_path, mode='w') as f:
     json.dump(each_manifest, f, ensure_ascii=False)

ちょっと長いですが、こちらを mk_manifest.pyというファイル名で保存します。 ただし、二箇所、どうしても書き換えねばならないところがありますので、 その箇所にコメントをつけています。その二箇所は 環境に応じて書き換えてください。

ここで、各ファイルの位置関係は、以下のようになっています。

---mk_manifest.py

---bib.csv

---0040_01---tiffファイル群

---0040_02---tiffファイル群

---0040_03---tiffファイル群

---0040_04---tiffファイル群

この状態で、以下のようにコマンドを走らせます。

% python3 mk_manifest.py bib.csv

そうすると、各画像フォルダの中に manifest.json ファイルができていると思います。これで、できあがりです。 ディレクトリ構成も適正になっている場合には、manifestファイル中のこのマニフェストファイルのURIを 示す@idを使ってWebブラウザで表示させてみてください。人間の目では見づらいですが、こんな風になって いれば多分大丈夫です。あとは、MiradorやUniversal viewer、IIIF Curation viewer、TIFYなどに読み込ませれば 普通に表示できるはずです。

閑話休題

さて、これを作った経緯についても簡単に書いておきますと、IIIF Manifestの書き方がよくわからない、という 話をしばしばいただいていて、そこがなんとなくハードルになっているように感じたためです。すでに 江草氏による解説記事も用意されていますが、もう少し別の角度から情報提供してみてもいいのかもしれないと 思って、こういうものをちょっと作ってご紹介してみました。

もう少し言えば、内製でこれから勉強して取り組まなければならない人がいる、ということを風の噂で耳にしたということもあります。

この記事は、少しだけプログラミングができる人を対象としたものです。ただ、本当に少々でいいというのが、上記のものを 見ていただくとわかると思います。CSVファイルの内容を読み込んで、画像の大きさとファイル名も読み込んで、 それらをIIIF Manifest の形にあわせてlist とdictを組み合わせて構造化し、最後にjsonとして書き出しをする、という 形になっています。画像フォルダの階層がもっと深い場合は glob.glob() に読み込ませるワイルドカードを 少し変更してみる、などの手立てが必要です。とはいえ、もっとエレガントな書き方もできますので、改良版を作成&公開してくださる人がおられたら 大変ありがたいところです。

画像フォルダとmanifestファイルの位置関係については、色々なやり方があると思いますので、場合によっては、 それにあわせてmanifestファイルの保存場所も変更したりする必要があるかもしれません。そこら辺は適宜 修正する必要があると思いますが、どうしてもよくわからないけどなんとかしたい・しなければならない という人はご相談ください。

なお、元々はPHPで書いていたものを簡素化してPythonで書き直したものですので、書き方にPHPっぽい(Pythonに最適化されてない)ところがあるかもしれませんが、 その点はご容赦ください。

IIIF Image サーバ (IIP Image server)構築のために(Python3+VIPSで)(Centos7用追記あり)

以前に、IIIF Imageサーバで大きな画像やたくさんの画像を高速に配信したい場合の有力な手段としてIIP Image serverのインストールの仕方をご紹介しました。

ただ、以前の記事では、「ピラミッド型タイル画像ファイルの用意」に関する説明があまり親切ではありませんでした。この点についての質問を時々いただくので、これについてもう少しご説明してみることにしました。

以前の記事ではImageMagickを使ったやり方を示していましたが、画像が多い場合はVIPSの方が高速で良いという話を聞きますので、VIPSを使った方法を見てみましょう。 動作環境は、Ubuntu18 + Python3です。

まず、こちらの指示に従って、VIPSを以下のコマンドにてインストールします。

% sudo apt install libvips-tools

これで依存関係のあるパッケージも一緒にインストールできるのではないかと思います。もしダメなら、その前に以下のコマンドでlibvipsそのものもインストールしておきましょう。

% sudo apt install libvips libvips-dev

次に、こちらの指示に従いつつ、Pyhon3環境があることを前提として、以下のコマンドにてインストールします。

% sudo apt-get install python3-gi gir1.2-vips-8.0

その後、以下のようにして、Pythonモジュールをダウンロード&設置します。

% sudo su

% wget https://raw.githubusercontent.com/jcupitt/libvips/8.4/python/packages/gi/overrides/Vips.py -O /usr/lib/python3/dist-packages/gi/overrides/Vips.py

これでVIPSをPython3から使えるようになったはずです。

次に、指定したフォルダ内のjpgファイル群からPyramid tif群をまとめて生成してみます。これは 以下のようなスクリプトでできました。

#!/usr/bin/python3
import sys
import gi
gi.require_version('Vips', '8.0')
from gi.repository import Vips
import glob
import os
file_names = sys.argv[1]+"/*.jpg"
list_file_names = glob.glob(file_names)
for file_path in list_file_names:
  new_file_path = os.path.splitext(file_path)[0] + ".tif"
  print(new_file_path)
  im = Vips.Image.new_from_file(file_path)
  new_file_path = new_file_path+'[compression=jpeg,Q=75,tile=1,tile-width=256,tile-height=256,pyramid=1]'
  im.write_to_file(new_file_path)

上記のスクリプトを mk_mani.pyというファイル名で保存した場合、

% python3 mk_mani.py [JPEG画像が保存されているフォルダ名]

という風にすると、上記のコマンドラインにて指定したフォルダの中の「.jpg」の拡張子を持つJPEG画像からPyramid Tiffファイルを生成できるはずです。

特にこれといった特別なことはしていませんが、ご参考になりましたら幸いです。

追記: Centos7で同じ事をするための手順も大体分かりましたので、とりあえず私の経験ということでご紹介しておきます。

まずはPython3をインストールしておきましょう。どうやら、baseリポジトリから入れられるようになっている みたいなので、epelやremiからインストールしてしまったという人はいったん削除してからbaseのものを 入れ直すと手順が楽になると思います。(削除することで他の問題が発生しそうだという場合は削除しないように お願いします)。

python3は開発パッケージも必要のようですので、

% sudo yum install python3-devel

としておきましょう。これでpython3がらみで必要なものはまとめてインストールされると思います。

それから、まだepelやremiをyumリポジトリとして設定していない人は、これを機会に設定して おきましょう。少なくともremiは以下の手順の中で必要になります。以下のサイトなどをご参考に。

https://www.kakiro-web.com/linux/remi-install.html

https://qiita.com/kodamacom/items/308f1c3e223d115103a9

さて、さっそくvipsのインストールなのですが、vipsの開発パッケージインストールのところで Remiに入っているlibwebp7-develが必要で、かつ、既存の libwebp-develとかち合ってしまうので既存のものは削除します。 そうすると、vips-develがインストールできるようになります。

% sudo yum erase libwebp-devel

% sudo yum --enablerepo=remi install libwebp7-devel

% sudo yum install vips-devel

ここからが、メモが甘くてややうろ覚えなのですが、

% sudo pip3 install pycairo

% sudo yum install gobject-introspection-devel

% sudo yum install cairo-gobject-devel

% sudo yum install pygobject3-devel

という風にしてから、最後に、以下のコマンドで、vips.pyを所定のディレクトリにダウンロードしておくと、 上記のようにPython3からVIPSを使えるようになりました。

% wget https://raw.githubusercontent.com/jcupitt/libvips/8.4/python/packages/gi/overrides/Vips.py -O /usr/local/lib64/python3.6/site-packages/gi/overrides/Vips.py

なるべくこまめにメモしながら作業したつもりですが、何か抜け落ちているかもしれず、うまくいかない場合は ご容赦ください。

デジタルアーカイブがサイズ感を得る時

まずはこちらの画像を見てください。何をしているのかというと、「サイズの異なる写真で、映り込んでいる定規をディープラーニングで解析してサイズをぴったりあわせて」います。 これで、2つの百鬼夜行絵巻のサイズの違い(片方は箱ですが)を、いちいちズームで調整することなく、ボタン一つで確認できるようになりました。

youtu.be

このサイズ調整機能を使うと、同じ二つ絵巻の内容を見るときも、二つの絵巻のなかのつづらのサイズはほぼ同じなのに片方の巻物は上下の余白が少ない、ということが簡単に確認できます。

youtu.be

デジタルアーカイブの画像は、これまで、ともすればサイズ感を見失ってしまいがちでしたが、このようにして簡便に 元サイズ同士の比率を反映した比較ができるようになると、これまでとはかなり印象が違ってくるようになると思います。

同時に、定規をいれて撮影することは、このように、技術の進歩によって非常に重要な要素になり得ることがわかります。

このビューワ自体はこちらで利用できます。ビューワ自体がまだそんなに使いやすくないですが、興味がある人はぜひお試ししてみてください。また、このビューワはgithub上で公開してますので、どなたでもソースコードを持って行って改良することができますので、もっと使いやすく作り直していただけますと大変ありがたく存じます。

さて、このようなものがどういう経緯でできたのかと言いますと、「ジャパンサーチ公開記念 GLAMデータを使い尽くそうハッカソン」という 国立国会図書館で開催されたイベントの中で作成されました。国立国会図書館でディープラーニング技術にも取り組んでいる青池亨さんが、私の無茶な要求に応えて開発して くださいました。

ここでどういうことが行われているのかというと、定規を移し込んだ画像を二つ重ねて表示してからサイズ調整ボタンをクリックすると、 こちらのビューワからは、IIIF Image APIで幅1024の画像のURLを2つ作ってGET Methodで送出し、あちら側では、おうかがいしている限りでは、 定規をディープラーニングで抽出してから、定規の目盛りをごにょごにょして(これはご本人に解説していただいた方がいいでしょう)サイズを取り出し、 二つの画像のサイズ比を返戻してもらいます。サイズ比を受け取ったら、あとはビューワの側でその数値に基づいてサイズを調整します。これで、 サイズ調整に際していちいち定規の目盛りを見ながら調整する必要がなくなりました。

ハッカソンというたったの二日間でこういうものを開発してしまう人が国立国会図書館で働いていて、さらに、そもそもそういう ものを開発しようという検討や、それをアプリに組み込んだりする時間と場を国立国会図書館が 提供してくれる、というのも、なかなかすごい時代になったものだと思います。

定規の入った二つの画像のサイズ比を取得する仕組みはAPIとして青池さんが公開しておられますので、使って見たい方は 上記のgithubのソースをみていただければと思います。この仕組みはさらに色々応用可能だと思いますので、今後の青池さんの ご活躍にはたいへん期待したいところです。

「デジタルアーカイブ研究」の観点?

今度、「第 7 回定例研究会:ジャパンサーチの課題と展望」というところでお話をさせていただくことになりました。 ここしばらくのジャパンサーチ試用は、そのご依頼を果たすための準備だったのですが、今回のご依頼は、実は使い勝手の 話ではなくて「 仕組み・社会的位置づけの観点から」ということでしたので、使い勝手の話は二の次です。 ここまでの試用を踏まえつつ、「 仕組み・社会的位置づけの観点から」の議論を組み立てようと思っております。 そこで、今回の研究会の紹介文を見てみますと、

第 7 回定例研究会:ジャパンサーチの課題と展望 (2019/9/24) | デジタルアーカイブ学会

試行版の評価や2020年に運用開始が予定されている正式版への期待・改善点の指摘などの議論を、デジタルアーカイブ研究の 観点から実施する。

という風になっており、ここには「デジタルアーカイブ研究の観点」という言葉が出てきます。しかしながら、 私はどちらかと言えばデジタルアーカイブの実践者であり、それを利用した研究やその基礎となる事についての研究はしておりますが、 デジタルアーカイブそのものの研究はあんまりしたことがないので、やや遠い立場ではありますが、少し気になっている点を整理してみたいと思います。

これまで、デジタルアーカイブに関わる研究集会としては、それをテーマとして長年掲げてきた じんもんこん(人文科学とコンピュータ)シンポジウムにずっと参加しておりましたので、 人文学向けのデジタル技術の応用という観点からのデジタルアーカイブについてはある程度議論ができるつもりでおりました。

しかしながら、デジタルアーカイブ学会の大会やデジタルアーカイブサミットに一般参加者として(一度、座長不在で急遽代理で座長を やる羽目になったことはありますが)ちょろちょろ参加させていただく中で、 議論が結構難しいということに気がつきました。たとえば、データの永続アクセスを保証しなければ、という 話をしようとすると、データを削除できなければコミュニティアーカイブでは問題だ、という話になり、 オープンアクセスの実現という話をしようとすると、有料でもアクセスできるならオープンアクセスだ(これは決して間違いではない)、 という話になり、定義に関する議論が大変なので、とりあえずは、とにかくデジタルコンテンツを集約した ものをデジタルアーカイブと呼ぼう、と言えば、コンテンツを持たない横断検索サイトもデジタルアーカイブに入れるべきだ、という 話がでてきたりして、「永続アクセスを保証するにはどうすれば」「無料で皆が自由にアクセスできるようにするには どうすれば」等の話に具体的に取りかかることが難しいことがあります。もちろん、「デジタルアーカイブ」全般について 考える際にコミュニティアーカイブのことを放置するなど話になりませんし、たとえ有料であっても門外不出の秘宝などを オープンにしていただけたのであればとてもありがたいことです。

そういうわけで、ここのところ、そういう状況を整理しながら議論する方法が 必要なのではないかと思っておりまして、そこで、議論を始める際に、以下のような見取り図を作ってみることを考えてみました。

f:id:digitalnagasaki:20190909030013p:plain

何か議論するときに、それぞれの項目について、どういう範囲を想定しているのか、ということを明示しながら話をすれば、 今は議論の対象になっていないだけで、論点を無視されているわけではないということが理解されやすくなって、 議論が多少進めやすくなるのではないかと思ったのです。これに従えば、たとえば、ユネスコ世界記憶遺産にも選ばれたかの有名な デジタルアーカイブは以下のようになると思います。(間違ってたらすみません)。

f:id:digitalnagasaki:20190909030353p:plain

あるいは、30万点の日本の歴史的典籍のデジタル化を目指す国文学研究資料館が有する巨大古典籍データベース、 日本古典籍総合目録データベースの場合、大体以下のような感じになるのではないかと思います。古典籍の中には 江戸時代の木版本もかなり含まれており、その中には、1点1点、刷りごとに微妙に異なるとは言え、 版が同じ複製本とも言えるようなものが含まれているので、複製物に少しシフトします。

f:id:digitalnagasaki:20190909030524p:plain

国立国会図書館デジタルコレクションの場合には、活版印刷本もたくさん入っているので複製物が 多いと考えることができます。永続アクセスが求められていて、著作権切れ資料はそのまま パブリックドメイン資料として公開していますが、一部に公開できないものもデジタル化してしまっていますので、 ちょっと飛んで「公開不可」にも丸がつきます。インターフェイスとしては一般向けを志向している面もあろうかと思います。 ということで、以下のような感じにしてみています。

f:id:digitalnagasaki:20190909030559p:plain

国宝をデジタル化したものを高精細画像で公開してくださっている貴重なサイト、e国宝だと以下のような感じでしょうか。

f:id:digitalnagasaki:20190909031005p:plain

一方、国立国会図書館東日本大震災アーカイブ(ひなぎく)の連携先の一番上に掲載されている「青森震災アーカイブ」を採り上げてみますと、おそらく 以下のように記述できるだろうかと思います。

f:id:digitalnagasaki:20190909031642p:plain

あるいは、今回の研究会を主宰する福島幸宏氏らが先週末のCode4Libジャパン2019で発表していた 「アーカイブズ構築のスリムモデル」であれば、大体以下のような感じに なるでしょうか。

f:id:digitalnagasaki:20190909032221p:plain

さて、ここでジャパンサーチの議論に戻りましょう。ジャパンサーチは統合検索を志向していますので、最終的には、こういった諸々のものをすべて 対象とした検索になるのだろうと想像されます。ですので、ジャパンサーチについて「どういうものをどう検索したいか」ということを 議論するのであれば、このような振れ幅を持つ色々な事項について議論することになると思われますので、お互いに、どの部分を前提として 議論しているのか、を時々確認しながら議論するとよいのではないかと思っております(が、いかがでしょうか?)。

なお、項目としては、他にも、

  • 「デジタルアーカイブ自体の位置づけ」:実験系⇔実装系

  • 「あるべき運営主体」:個人系⇔組織系

といったものも入れてみてもいいかもしれません。他にももしあればご提案いただけますと幸いです。

ようやく刊行にこぎつけました:『日本の文化をデジタル世界に伝える』

『日本の文化をデジタル世界に伝える』というやや大仰なタイトルの本を刊行することになりました。

www.jusonbo.co.jp

京都大学人文科学研究所で共同研究班をやらせていただいた時の成果物の刊行という位置づけのものですが、終了後、かなり時間が経ってからの刊行となりました。共同研究班が終了する頃にIIIFが流行り始めたりTEIの日本語圏への導入が本格化したりましたので、その後の状況もかなり追記しております。共同研究班で議論してきたことをまとめたものではありますが、執筆は一人で行いましたので、基本的に私の主観がかなり入っており、議論そのものを忠実に反映したとは言えない面があります。また、わかりやすさの優先や私の理解不足から、記述に甘いところや間違いなども含まれていると思いますが、それらについてはすべて私の責任ですのでご容赦ください。

本書の目次は以下のようになっています。

第1章 「デジタル世界に伝える」とは

第2章 デジタル世界への入り口

第3章 利便性を高めるには?

第4章 デジタル世界に移行した後,なるべく長持ちさせるには

第5章 可用性を高めるための国際的な決まり事:IIIFとTEI

第6章 実際の公開にあたって

第7章 評価の問題

第8章 研究者の取り組みへの評価の問題

いわゆる文化資料に関わるデジタルアーカイブの構築についての技術論です。といっても、数式やプログラミングの話はほとんどでてきません。基本的に、「技術をどう使うべきか。どう使った方がいいか」という話に徹しています。というのは、現在の日本のデジタルアーカイブの議論では、技術論をもう少しきちんと踏まえた方がよいと考えているのですが、議論のためのたたき台のようなものがあまり十分でないように感じておりまして、そのたたき台を提供することを一つの目標としたのでした。

本書の編集主体である共同研究班のメンバーの方々は、私も含めて、研究開発や実運用の経験をベースにそういう議論をずっとしてきたコミュニティに色々な形でつながっていて、議論の蓄積もかなりあり、それらは主に、情報処理学会・人文科学とコンピュータ研究会の研究報告・シンポジウム論文集や、「東洋学へのコンピュータ利用セミナー」の発表論文集などに散在しています。しかしながら、その蓄積は、30年以上にわたって書かれてきた1000件以上の玉石混交の論文・研究報告から成っているものであり、たとえばデジタルアーカイブに関わる方々が皆、有用な情報を求めてそれらを読み始めなければならないという状況はあまりにも無茶なことです。本書は、そのような背景から、文化資料デジタル化に関する今後のデジタルアーカイブ構築の議論において有用と思われる要素をピックアップして紹介してみております。言い方を換えると、これまであちこちで色々な相談をいただくなかで、よく聞かれるポイントをなるべく押さえています。(ですので、このブログに書いてあるような事柄もかなり含まれています。特にこのブログをよく読んでいる人には既知のことが多いと思いますが、まとまった話として読めるという点では有用かと思います。)

 なお、構築、というのは、応用に関することはまた別途執筆する予定がありますので、ここでは構築に限っているということであり、したがいまして、いくつかの先進的な応用事例の話は出てきません。また、「デジタルアーカイブ」という言葉をタイトル等に出さなかったのは、デジタルアーカイブの重要な要素であるコミュニティアーカイブや重文国宝級資料のデジタルレプリカアーカイブ等の話にほとんど触れていないためです。ただ、話としては通じることも色々あると思いますので、そういったことに取り組んでおられる方々にも目にしていただけるとありがたいと思っております。

IIIF画像同士を重ねてみるViewerを作りました:その1・機能の紹介

先週、数人の知り合いの人文系開発者の方々と、一緒に集中的に開発やデータ作成をしようということで、南房総の方で合宿をしてきました。年甲斐もなく、自分も開発に集中してしまったのですが、どうしてもよくわからなかった事柄の理解を中心に、かなり集中することができまして、ようやく、IIIFの画像同士をWebブラウザ上で重ねるという、これまで目指していたものの一つができました。

とにかく、見ているIIIF画像をピックアップしてためておいて、重ねたい対象に重ねて位置合わせをする、というだけのものです。が、言うは易し。誰かがこういうものを作ってくれるだろうなと ずっと待っていたのですが、なかなか出てこないので、結局自分で作ってみることにしたのがこちらです。

youtu.be

同じIIIFコンテンツ内でも、複数のIIIFコンテンツ同士でも、重ねて位置合わせをしたり透過度を調整したりすることができます。重ねた画像に関しては、まとめてJSONデータとして 出力するようになっていますので、これをテキストエディタに保存しておけば、同じビューを再現して、さらにそこから重なりや透過をいじることができます。

youtu.be

実際のサイトは以下のURLなのですが、これは全部Javascriptで書いてますので、サーバ上でなくてもパソコン上でも動作します。

http://candra.dhii.jp/nagasaki/iiifoverlay/viewer.html

たとえば、このサイトで、「Open JSON Window」ボタンをクリックしてウインドウを開いて、以下のJSONデータをコピペして「Load JSON」ボタン⇒「Set Positions」ボタン クリックしていくと、上記の曼荼羅+大日如来2つの透過重ねが再現できて、自分でも色々いじることができます。

{
    "@context": "http://iiif.io/api/presentation/2/context.json",
    "@type": "sc:Manifest",
    "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/12b02/manifest.json",
    "label": "大正新脩大藏經図像部第12b02巻",
    "metadata": [
        {
            "label": "Author",
            "value": "高楠順次郎"
        },
        {
            "label": "published",
            "value": [
                {
                    "@value": "大蔵出版",
                    "@language": "ja"
                }
            ]
        },
        {
            "label": "Source",
            "value": "大正新脩大藏經 図像部"
        },
        {
            "label": "manifest URI",
            "value": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/12b02/manifest.json"
        }
    ],
    "description": "大正新脩大藏經図像部",
    "viewingDirection": "right-to-left",
    "viewingHint": "paged",
    "license": "http://creativecommons.org/licenses/by-sa/4.0/",
    "attribution": "大蔵出版(Daizo shuppan) and SAT大蔵経テキストデータベース研究会(SAT Daizōkyō Text Database Committee) ",
    "logo": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/satlogo80.png",
    "sequences": [
        {
            "@id": "https://dzkimgs.l.u-tokyo.ac.jp/zuzoubu/12b02/sequence.json",
            "@type": "sc:Sequence",
            "label": "Current Page Order",
            "canvases": [
                {
                    "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/p0024",
                    "@type": "sc:Canvas",
                    "label": "p.24:図像抄",
                    "width": 6732,
                    "height": 8984,
                    "images": [
                        {
                            "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/ano0024",
                            "@type": "oa:Annotation",
                            "motivation": "sc:painting",
                            "resource": {
                                "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/03/0024.tif/full/full/0/default.jpg",
                                "@type": "dctypes:Image",
                                "format": "image/jpeg",
                                "width": 6732,
                                "height": 8984,
                                "service": {
                                    "@context": "http://iiif.io/api/image/2/context.json",
                                    "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/03/0024.tif",
                                    "profile": "http://iiif.io/api/image/2/level1.json"
                                }
                            },
                            "on": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/p0024"
                        },
                        {
                            "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/01/ano1000",
                            "@type": "oa:Annotation",
                            "motivation": "sc:painting",
                            "resource": {
                                "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/01/1000.tif/full/full/0/default.jpg",
                                "@type": "dctypes:Image",
                                "format": "image/jpeg",
                                "width": 6732,
                                "height": 8984,
                                "service": {
                                    "@context": "http://iiif.io/api/image/2/context.json",
                                    "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/01/1000.tif",
                                    "profile": "http://iiif.io/api/image/2/level1.json"
                                }
                            },
                            "on": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/p0024#xywh=2818,3699,985,1314",
                            "license": "undefined",
                            "attribution": "undefined"
                        },
                        {
                            "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/ano0024",
                            "@type": "oa:Annotation",
                            "motivation": "sc:painting",
                            "resource": {
                                "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/03/0024.tif/full/full/0/default.jpg",
                                "@type": "dctypes:Image",
                                "format": "image/jpeg",
                                "width": 6732,
                                "height": 8984,
                                "service": {
                                    "@context": "http://iiif.io/api/image/2/context.json",
                                    "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiifimgs/zuzoubu/03/0024.tif",
                                    "profile": "http://iiif.io/api/image/2/level1.json"
                                }
                            },
                            "on": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/p0024#xywh=2814,3708,1023,1366",
                            "license": "undefined",
                            "attribution": "undefined"
                        }
                    ],
                    "otherContent": [
                        {
                            "@id": "https://dzkimgs.l.u-tokyo.ac.jp/iiif/zuzoubu/03/list/p0024.json",
                            "@type": "sc:AnnotationList"
                        }
                    ]
                }
            ]
        }
    ]
}

まだまだ色んな機能を追加できる可能性がありますので、どなたか頑張ってくださったらありがたいとも思っております。

頑張ってくださるどなたかのために(企業の方でもぜひ挑戦・採用などしていただけるとありがたく思います)、今回苦労した部分を少しご紹介しておきたいと思います。

基本的に、苦労したことの大半は、IIIFのタイル画像表示をしてくれるOpenSeadragonのAPIの仕様を理解すること だったので、少しずつご紹介してみたいと思います。

まず、複数のIIIFタイル画像を一つのビューワで表示する関数なのですが、透過度0.7で左上位置をそろえて 表示させる場合、以下のようにしてできるようです。imgUriは、何か適当に info.jsonのURLを入れればOKです。

viewer.addTiledImage({
          tileSource: imgUri,
          opacity: 0.7,
          index:10,
          x:0,
          y:0
        });

重ねた画像の位置を変える際には

viewer.world.getItemAt(n).setPosition({x:0,y:0.5});

という感じにするのですが、タイル画像を重ねていくと、最初のタイル画像がn=0で、 それに一つ重ねるとn=1、二つ重ねるとn=2、という風に増えていきます。 同様に、nの値をあわせることで、透過度や画像のサイズも変えられます。ただし、縦横比を変えるのは ちょっと無理っぽい感じでした。

viewer.world.getItemAt(n).setOpacity(0.8);
viewer.world.getItemAt(n).setWidth(1.5);

OpenSeadragonのハマりやすいポイントの一つは、画像の横幅に対する相対値として縦横幅高さ(x,y,w,h)の値が表現されるという点です。 ですので、とにかく画像の横幅のサイズを取得する必要があります。これは以下のように getContentSize().x で取得できます。

viewer.world.getItemAt(n).getContentSize().x; 

なお、「重ねた画像の位置を動かす」際に、元の画像を動かさずに重ねた画像の位置だけをドラッグで動かす方法については 色々試したのですが、結局のところ、「重ねた画像を動かす際には viewer.setMouseNavEnabled(false); で 元画像や他の重ねた画像の動きを全部止めて重ねた画像の位置だけをjQueryで動かす」という風にしました。

とりあえず、今夜はこんなところにしておきます。

サーチしないジャパンサーチ(BETA)~ジャパンサーチを探検 その6

前回記事の最後で触れたように、検索しない使い方も提供されているようですので、少し気分を変えて、検索しない場合はどういう風に使えそうなのか、ちょっとみてみます。

「ジャパンサーチ」と言われると、検索窓を探してしまいますが、その名前を忘れてみて、たとえば、「これは検索サイトではない、ジャパンコンテンツだ」などと念じながら ジャパンサーチのページを開いています。そうすると、少し気持ちが変わって、扉ページで提供されているものをじっくりみてみようか、と思うようになりました。

まずは扉絵を見ていると、じわーっと動いています。解説もついています。なぜこのコンテンツが選ばれているのかよくわかりませんが、 なかなかよい文化資料ですね。しばらく見ていると次の画像に切り替わって、またじわーっと動いていきます。この動き方は、 資料にあわせてカスタマイズしているのでしょうかね。掲載時に、簡単にこの動き方の設定ができるようになっているといいですね。 一次停止ボタンとか次の画像に移るボタンもありますが、次の画像に移るボタンは、扉の絵がたくさん提示されるようになることも 想定されているのでしょうかね。蓄積されていくとどうなるでしょうね。また、「あのとき見た扉絵」というのが、あとから 再確認できるとありがたいかもしれないですね。誰かの物語の一部になるかもしれません。扉絵をクリックすると扉絵の コンテンツ情報が表示されたりお気に入りボタンも出てきたりするので、自分でノートにメモしておくことはできそうですね。 ただ、このノートのデータ、LocalStorageに入れておくだけだと、持続性とか再利用性とかちょっと難しいですが、 今後はどうなるでしょうね。

その下にいくと「ギャラリー」というのがあります。「富士山」「もう一つの東京オリンピック」など、お役立ち情報とともに デジタルアーカイブ画像が引用されたりしているようです。これもなかなかいいですね。デジタルアーカイブの活用の 仕方の模範的な例だと思います。ただ、このあたりになると、むしろ、書籍や雑誌のような有料コンテンツと 競合してしまわないだろうか、というあたりが少し気になります。競合と言っても、無料であれば有料とは競合には ならないのですが、有料コンテンツにお金を払う人がますます減るのではないかという気もします。お金が回らなく なると、それでやっていくプロが減っていってしまうので、全体としての質の向上もやや難しくなっていくような 気がします。いずれは無料コンテンツが世界を制覇するのかもしれないとは思いますが、そうだとしても、 プロが急激に減ってしまうよりはプロとの共存期間を経て無料コンテンツが鍛えられていくような流れがあると いいのかなとも思います。また、利用は無料でも制作者はどこかからお金をもらう、という在り方ももちろん ありますし、ギャラリー制作者はお金をもらっている(人もいる)かもしれませんが、そうすると今度は、 お金を払う人に内容が多かれ少なかれ制限されてしまわないかなということも気になります。本件一つをもってどうこうという わけではないのですが、全体的な流れとして、オープンデータ・オープンアクセス・オープンサイエンス といったことについて考えてみると、有料であることによって保たれてきた自由や質の在り方が、 今後ずいぶん変わっていくのだろうとも思います。

さて、話が少し脱線しましたが、もう一つ気になるのは、Wikipediaとの関係でしょうか。正直に言えば、 Wikipedia大好きです。特に、よく採り上げられますが、「地方病 (日本住血吸虫症) - Wikipedia」の記事は最高です。近代日本の医療の歴史だけでなく、甲陽軍鑑や明治期の薬の広告、地図、統計情報等々、Web上のマルチメディアコンテンツ を縦横無尽に駆使した圧倒的な記事です。結構昔からこの記事を何度も読んでいますが、着実なアップデートを重ねて、 新たなWebコンテンツもあれこれと吸収しながら現在に至っているという点も素晴らしいことです。 この記事などはジャパンサーチの「ギャラリー」に載っていても全然おかしくないものではないかと いう気がします。

経験上、似たようなものがあれば1つにまとめればよいという考え方は必ずしも適切であるとは限らないと 思っておりまして、むしろ、似たようなものが複数共存することで相互に高め合っていけるとよいのではないかと 思っております。似ていることが、双方の目的意識を先鋭化してレベルアップにつながるということも 多々あるように思います。ですので、似ているからと、どちらかにしてしまえ、ということではないのですが、 何かこう、よいものは何らかの形で連携できるといいのかなあ、とは思っております。

また、「ギャラリー」に今後何を載せていくか、ということも気になるところです。個人的に関心のあることが 掲載されてくれるとありがたいとは思いますが、時事的なことでデジタルアーカイブを渉猟する時間がないとき など、「ギャラリー」で適宜情報を集めて掲載しておいてもらえると、見やすくなってありがたいとも思います。 ただ、そういう情報にお金を払わなくて済んでしまう世界というのは、どういうことなんだろうか、ということも 考えてしまうところです。個々の画像は著作権切れてますし、情報収集の費用を低減させることでより広い 読者に情報提供できるようにして教育・学習の機会を増やしていくことは大事ですし、ネットにばらまかれる 色々なおかしなデマ情報に対抗するためには、きちんとした情報にも無料でアクセスできるようにすることは 大切です。ただ、個々の読者ではなく、スポンサー側(この場合政府自治体も含む)が執筆の対価を支払う(= 執筆者の選択や執筆内容にも発言力を持つ)という世界がどういう方向に進んでいくのか、ということは やはり注意しておかざるを得ないだろうと思っております。もちろん、クラウドファンディングとかもあります ので、場合によってはそういう方向を考えることになるのだろうかとも思いますが、いずれにしても、紙媒体を前提とした 商業出版が形成していた世界とはかなり違ったものになっていくのでしょう。

さて、脱線が続いてしまいましたが、「ギャラリー」は色々見られてよいですね。こんなコンテンツがあるなら、 こういうコンテンツもないだろうか、と、ジャパンサーチ自体を検索してくれる人も出てくるかもしれません。 さあ、検索・・・と、右上の虫眼鏡アイコンをクリック、でしたね。やはり、すぐに検索にいけるようになって いるとありがたいですね。

それと、ジャパンサーチはコンテンツがどんどん増えていくという前提だろうと思いますので「ギャラリー」も それに応じて、時々でもアップデートできるとありがたいですね。あるいは、細々追加するのはどんどん 大変になっていくので、むしろ、新規登録コンテンツを見て 関連する情報があればサジェストするようなものをユーザ向けページに組み込んでおくという手もある かもしれないですね。「この記事の執筆以降に追加された関連コンテンツ」のような項目で。 そうすると、メタデータ項目として「ジャパンサーチに追加された日時」もあると便利でしょうかね。

というわけで、きれいなものを見て心が洗われたような気持ちになっていますが、ジャパンサーチ(BETA)をサーチしないでの探検はこれくらいに しておきたいと思います。