ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Rampをカスタマイズする

Rampをカスタマイズする

概要 Rampのカスタマイズ方法に関する備忘録です。カスタマイズの結果、以下のように、UIの一部を日本語化し、メディアプレイヤーとメタデータおよび文字起こしを左右に並べて表示します。また、クエリパラメータtを使って、音声の再生開始時間を指定できるようにします。 例えば、以下のURLから、140秒時点から再生することができます。 https://ramp-iiif.vercel.app/?iiif-content=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json&t=140 以下がカスタマイズ前です。 セットアップ 以下の記事の参考にしてください。 カスタマイズ 音声の再生開始時間の指定 以下のマニュアルにおいて、startCanvasTimeプロパティが使えることがわかります。 https://samvera-labs.github.io/ramp/#!/IIIFPlayer そこで、以下のindex.jsファイルに対して、startCanvasTimeをクエリパラメータから取得する処理を追加します。 import React from 'react'; import ReactDOM from 'react-dom'; import App from './app'; // import config from './config'; const manifestURL = () => { const params = new URLSearchParams(window.location.search); // let url = `${config.url}/manifests/${config.env}/lunchroom_manners.json`; let url = "https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json" if (params.has('iiif-content')) { url = params.get('iiif-content'); } return url; }; const startCanvasTime = () => { const params = new URLSearchParams(window.location.search); if (params.has('t')) { return parseFloat(params.get('t')); } return 0; } ReactDOM.render(<App manifestURL={manifestURL()} startCanvasTime={startCanvasTime()} />, document.getElementById('root')); そして、app.jsに対して、startCanvasTimeプロパティを与えます。これにより、クエリパラメータから、メディアの再生開始時間を指定できます。 ... <IIIFPlayer manifestUrl={manifestUrl} startCanvasTime={canvasTime} > ... 日本語化およびレイアウトの変更 上記と同様、demo/app.jsファイルを編集することで、日本語化およびレイアウトの変更を行うことができます。 Vercelへのデプロイ Build & Development Settingsを以下のように指定します。 Build Commandにnpm run demo:build、Output Directoryにdemo/distを設定します。 また、Node.js Versionを18.xにする必要がありました。20.xの場合、パッケージのインストール時にエラーが発生しました。 まとめ Rampの開発に関わる方々に感謝いたします。RampおよびIIIF Presentation API v3の利用にあたり、参考になりましたら幸いです。 ...

Rampをローカルで起動する

Rampをローカルで起動する

概要 Rampをローカルで起動してみましたので、備忘録です。 背景 Rampは以下のように説明されています。 Interactive, IIIF powered audio/video media player React components library. (日本語訳)インタラクティブな、IIIF対応のオーディオ/ビデオメディアプレイヤーReactコンポーネントライブラリ 以下のGitHubリポジトリでソースコードが公開されています。 https://github.com/samvera-labs/ramp 起動 以下で起動できました。 git clone https://github.com/samvera-labs/ramp pnpm i pnpm demo 以下に記載があります。 https://github.com/samvera-labs/ramp?tab=readme-ov-file#styleguidist-development 以下の場合は、スタイルガイドのページが表示されますので、ご注意ください。 pnpm dev まとめ 参考になりましたら幸いです。

URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試す

URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試す

概要 URLの引数で指定したIIIFマニフェストに対して、Mirador 3のannotationsプラグインを試すことができるデモページを用意しました。 https://mirador-annotations.vercel.app/ iiif-contentまたはmanifest引数を使用することで、指定したIIIFマニフェストを対象にすることができます。 https://mirador-annotations.vercel.app/?iiif-content=https://dl.ndl.go.jp/api/iiif/1301543/manifest.json 本記事は、このデモページの作成に関する備忘録です。 背景 Mirador 3向けのアノテーション付与プラグインとして、mirador-annotationsがあります。 https://github.com/ProjectMirador/mirador-annotations 以下の記事で使い方の例を紹介しています。 そして、以下のデモページがすでに用意されていますが、URLの引数にIIIFマニフェストファイルを指定する機能は提供されていません。 https://mirador-annotations.netlify.app/ フォークと修正 URLの引数にIIIFマニフェストファイルを指定する機能の追加にあたり、上記のリポジトリをクローンしました。 https://github.com/nakamura196/mirador-annotations そして、以下の修正を加えました。 https://github.com/nakamura196/mirador-annotations/commit/18848ccb1fa51df821335ed76e7b9f4e974527d0 特に、以下の修正を加えています。 ... var params = new URL(document.location).searchParams; var manifest = params.get('iiif-content') || params.get('manifest') || 'https://iiif.harvardartmuseums.org/manifests/object/299843' var windows = []; if (manifest) { windows.push({ manifestId: manifest }); } ... これは、以下の実装を参考にしています。iiif-contentまたはmanifest引数でIIIFマニフェストファイルを参照するようでした。 https://projectmirador.org/embed/?iiif-content=https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json Vercelへのデプロイ設定 フォークしたリポジトリのソースコードをビルドした結果を、Vercelにデプロイしています。 デプロイにあたり、以下のような修正を加えました。 Output Directory、Install CommandおよびNode.jsのVersionを16.xに変更しています。 まとめ Mirador 3の利用にあたり、参考になりましたら幸いです。

mdx.jpのオブジェクトストレージとCantaloupe Image Serverを使ってIIIF画像を配信する

mdx.jpのオブジェクトストレージとCantaloupe Image Serverを使ってIIIF画像を配信する

概要 mdx.jpのオブジェクトストレージとIIIFイメージサーバの一つであるCantaloupe Image Serverを使ってIIIF画像を配信する方法に関する備忘録です。 背景 以下の記事で、mdx.jpのオブジェクトストレージを使った画像の配信方法について紹介しました。 また以下の記事で、Cantaloupe Image Serverで、Amazon S3に格納した画像を配信する方法について紹介しました。 これらを組み合わせることにより、デジタルアーカイブにおけるIIIF画像配信コストの課題の解決を目指します。 方法 以下の記事で紹介したDocker版Cantaloupeを使用します。 以下のリポジトリから、ソースコードをダウンロードいただけます。 https://github.com/nakamura196/docker_cantaloupe_s3 同梱されている.env.sampleを.envファイルにリネームし、設定を変更します。 # aws s3 CANTALOUPE_S3SOURCE_ENDPOINT= # mdx.jp # CANTALOUPE_S3SOURCE_ENDPOINT=https://s3ds.mdx.jp CANTALOUPE_S3SOURCE_ACCESS_KEY_ID= CANTALOUPE_S3SOURCE_SECRET_KEY= CANTALOUPE_S3SOURCE_REGION= CANTALOUPE_S3SOURCE_BASICLOOKUPSTRATEGY_BUCKET_NAME= ポイントはCANTALOUPE_S3SOURCE_ENDPOINTです。ここに、https://s3ds.mdx.jpを与えて、取得したACCESS_KEY_IDやSECRET_KEY、作成したBUCKET_NAMEやREGIONを設定します。 デモ 冒頭の記事でも使用した、いらすとやさんの画像を利用します。 https://www.irasutoya.com/2016/09/blog-post_810.html 以下、上記でアップロードした同じ画像ファイルを、Cantaloupeを使って配信している例です。 info.json https://cantaloupe.aws.ldas.jp/iiif/3/baby_asia_boy.png/info.json グレー化: full/max/0/gray.jpg https://cantaloupe.aws.ldas.jp/iiif/3/baby_asia_boy.png/full/max/0/gray.jpg なお、Cantaloupeを使って画像配信を行う場合には、上記の記事で実施したACLの設定(EveryoneにRead権限を与える)は不要です。デフォルトの設定を使用することで、オブジェクトストレージ上の画像ファイルへの直接アクセスは不可としつつ、Cantaloupeを介したアクセスのみを許可できるかと思います。 以下の記事で紹介したようなCantaloupe側のAccess Control設定を組み合わせることで、アクセス制御を実現することになるかと思います。 まとめ Amazon S3に格納した画像をIIIF画像として配信する方法として、以下の方法もあります。これが、Amazon S3以外のオブジェクトストレージにも対応しているのか、今後調査してみたいと思います。 IIIF画像の配信にあたり、参考になりましたら幸いです。

Mirador 3でScroll Viewを使う

Mirador 3でScroll Viewを使う

概要 Mirador 3でScroll Viewを使う方法についての備忘録です。 以下、「鹿児嶋征討記之内 高瀬口河通ノ戦争野津公聯隊旗を取返ス図(国立国会図書館所蔵)」を例としています。 このIIIFマニフェストは3つのキャンバス(画像)から構成されており、通常の表示方法(Single, 単一モード)では、画像ごとに表示されます。 これを3つ繋げて表示することを目指します。 デモ 以下からお試しいただけます。 https://nakamura196.github.io/mirador-multi-image/ IIIFマニフェストファイルについては、国立国会図書館で公開されているIIIFマニフェストファイルを一部変更しています。 変更前 https://dl.ndl.go.jp/api/iiif/1301543/manifest.json 変更後 https://nakamura196.github.io/mirador-multi-image/manifest.json 変更箇所として、今回の記事の目的であるScroll表示と直接関係がありませんが、画像が右から左に表示されるように、"viewingDirection": "right-to-left"を追加しています。 Miradorの設定 Mirador 2では事前設定なしにScroll Viewが使えましたが、Mirador 3のデフォルト設定では、Scroll Viewは無効化されているようでした。 https://projectmirador.org/embed/?iiif-content=https://nakamura196.github.io/mirador-multi-image/manifest.json そこで、Mirador 3の初期設定を以下のように修正します。 https://github.com/nakamura196/mirador-multi-image/blob/main/docs/index.html const config = { id: "mirador", windows: [ { manifestId: "./manifest.json", }, ], language: "ja", window: { sideBarOpenByDefault: true, defaultSideBarPanel: "info", defaultView: "scroll", views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }], }, }; Mirador.viewer(config); ポイントは、views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }]です。ここで、Scroll Viewを追加することで、以下のように選択肢として表示されるようになりました。 参考 defaultView未指定時のバグ デフォルト表示を未指定の場合、上記の例ではSingle(単一)表示が使用されますが、その状態からScroll Viewボタンを押すと、表示がうまく切り替わらないケースがありました。 この問題について、上記のように、defaultView: "scroll"を設定しておくことで回避できました。根本的な解決方法は改めて調査したいと思います。 ...

IIIF対応ビューアの一覧の調査例

IIIF対応ビューアの一覧の調査例

概要 IIIF対応のビューアの一覧にあたり、調べてみた例を共有します。不足している点も多いかと思いますが、参考になりましたら幸いです。 Name URL Icon Mirador https://projectmirador.org/embed/?iiif-content= mirador3.svg Universal Viewer https://uv-v3.netlify.app/#?manifest= uv.jpg Annona https://ncsu-libraries.github.io/annona/tools/#/display?url= annoa.png Clover https://samvera-labs.github.io/clover-iiif/docs/viewer/demo?iiif-content= clover.png Glycerine Viewer https://demo.viewer.glycerine.io/viewer?iiif-content= glycerine.jpg IIIF Curation Viewer http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/?manifest= icp-logo.svg Image Annotator https://www.kanzaki.com/works/2016/pub/image-annotator?u= ia-logo.png TIFY https://tify.rocks/?manifest= tify-logo.svg 参考 以下のIIIF 3.0 Viewer Matrix などが参考になりました。 https://iiif.io/api/cookbook/recipe/matrix/#basic-recipes

Chromeでサイズが大きい動画が再生できない

Chromeでサイズが大きい動画が再生できない

概要 Chromeにおいて、サイズが大きい動画が再生できないことがありました。一方、Safariでは再生できました。 開発者ツールで確認すると、ダウンロードがキャンセルされていました。 ビューア部分は以下のようになっています。 <video controls="controls" preload="none" style="width: 620px; height: 465px;" width="100%" height="100%"> <source src="https://omeka.aws.ldas.jp/files/original/c486fe4ae8d926034678fa11b0d6b2fd55b0e695.mp4" type="video/quicktime" title="undefined"> </video> このHTMLは、以下の記事で紹介した、Omeka S + IIIF Serverの組み合わせによって作成されたものです。 原因 先ほどのhtmlを確認すると、type="video/quicktime"となっており、拡張子はmp4となっていますが、中身は異なる(movファイル?)ことがわかります。 おそらく動画の拡張子のみが変更され、Omeka Sに登録された際、Omeka Sが中身からtypeを指定したように思われます。 Safariで再生できたのも、これが原因かと思われます。 対処法 例えば、macの場合は、以下によりmp4に変換できます。 brew install ffmpeg ffmpeg -i aaa.mov aaa.mp4 まとめ Omeka Sなどで動画ファイルを配信する際の参考になりましたら幸いです。

IIIFのCanvas URIなどを一括置換する際のコマンド

IIIFのCanvas URIなどを一括置換する際のコマンド

複数のIIIFマニフェストファイルに対して、Canvas URIを一括置換したい場合があります。 例えばカレントディレクトリ以下のJSONファイルに対して、www.dl.ndl.go.jpをdl.ndl.go.jpに置換したい場合のコマンドは以下です。-i ''オプションは macOS 特有の構文です。 find . -type f -name "*.json" -exec sed -i '' 's/www\.dl\.ndl\.go\.jp/dl\.ndl\.go\.jp/g' {} + 注意: このスクリプトはファイルを直接変更します。重要なデータに対して使用する前には、必ずバックアップを取るなどの対策をお勧めします。また、バイナリファイル(画像や実行ファイルなど)に対してテキスト置換を行うとファイルが壊れる可能性があるため、適用するファイルの種類には注意してください。 参考になりましたら幸いです。

Omeka SのBulkImportを使用する際の設定例

Omeka SのBulkImportを使用する際の設定例

概要 Omeka SのBulkImportを使ってデータの一括登録を行う際、登録方法の各種設定を行うことができます。 これはアップロードの都度、設定することもできますが、事前に登録しておいた設定を使用するようにすることで、作業者によるミスなどを軽減することができます。 ここでは、登録済みのアイテムに対して、IIIF画像を紐づける際の、一括登録用の設定例について紹介します。 アイテムの例 以下のように、dcterms:identifierにsampleを持つアイテムを作成しておきます。 設定 以下にアクセスします。 /admin/bulk/bulk-import 登録するフォーマットに合わせて、「CSV - Medias」または「OpenDocument spreadsheet (ods) - Medias」の編集アイコンをクリックします。 Importer タブにおいて、MapperをManualに設定します。これにより、登録時にマッピング結果を確認できるように、マッピングミスの有無などを確認できるようになります。 またProcessor タブにおいて、Identifier to use for linked resources or updateをdcterms:identifierに設定します。これにより、CSVやODSファイルにおいて、メディアを紐づけるアイテムをdcterms:identiferで指定できるようになります。 データ例 以下のようなデータを用意します。 iiif o:item dcterms:source https://dl.ndl.go.jp/api/iiif/3437686/R0000001/info.json sample https://dl.ndl.go.jp/api/iiif/3437686/R0000001/info.json CSVまたはODSファイルの項目の指定方法については、以下などを参考にしてください。 https://nakamura196.hatenablog.com/entry/2021/07/28/080952#アイテム マッピング表は以下にあります。 https://gitlab.com/Daniel-KM/Omeka-S-module-BulkImport/-/blob/master/data/mappings/fields_to_metadata.php 登録 Step 1/4: Reader において、ファイルを選択します。 (基本的には作業不要)Step 2/4: Mapper において、登録対象のリソースの数や、マッピング結果に問題がないかを確認します。 (基本的には作業不要)Step 3/4: Processor において、Identifier to use for linked resources or updateで先に設定した値が登録されているかを確認します。 (作業不要)Step 4/4: Confirmation において、画面右上の「Start import」ボタンを押します。 ...

Omeka SのIIIF ServerモジュールでのCORSエラー

Omeka SのIIIF ServerモジュールでのCORSエラー

概要 Omeka SのIIIF Serverモジュールを使ってIIIFマニフェストを配信した際、外部のビューア等で以下のCORSエラーが発生しました。 Access to fetch at 'https://xxx/iiif/2/09fd29d5-8497-4def-a64d-ca104284f90d/manifest' from origin 'https://universalviewer.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 本記事では、Omeka SでのCORSエラーへの対策について紹介します。 対策 https://github.com/Daniel-KM/Omeka-S-module-IiifServer?tab=readme-ov-file#cors-cross-origin-resource-sharing 以下を追加しました。 SetEnv APPLICATION_ENV "production" ... </FilesMatch> Header setIfEmpty Access-Control-Allow-Origin "*" Header setIfEmpty Access-Control-Allow-Headers "origin, x-requested-with, content-type" Header setIfEmpty Access-Control-Allow-Methods "GET, POST" これにより、CORSの問題を解決することができました。 ...

LEAF Writer: Image Viewerの使い方

LEAF Writer: Image Viewerの使い方

概要 LEAF Writerでは、以下のように、テキストと画像を並列表示する機能を提供します。画像のページをおくると、テキストも連動して動作する機能も提供されています。 このImage Viewer部分に画像を表示するための、TEI/XMLの記述例を紹介します。 方法 以下のように、pbタグを指定します。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/xml/lw/01.xml 具体的には、以下です。 ... <pb corresp="#zone_0005" facs="https://dl.ndl.go.jp/api/iiif/3437686/R0000022/0,0,3445,4706/full/0/default.jpg" n="5"/> ... pb要素のfacs属性に指定された画像が、Image Viewer部分に表示されるようでした。 まとめ 近年、TEIとIIIFを組み合わせて利用するケースも多いです。 https://github.com/TEI-EAJ/jp_guidelines/wiki/IIIF画像とのリンク 上記のような記法に基づき、IIIF Image APIと連動するようなLEAF WriterのImage Viewerの開発にも取り組みたいと思います。 またその延長として、Oxygen XML Editorのアノテーション機能のようなツールも用意できればと思います。 LEAF Writerの利用にあたり、参考になりましたら幸いです。

RDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係を理解する

RDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係を理解する

概要 IIIFマニフェストがJSON-LDで記述されていることを確認するため、他のフォーマットに変換してみましたので、備忘録です。 RDFと、JSON-LDやTurtleなどのファイルフォーマットの関係、およびJSON-LDによって記述されているIIIFマニフェストファイルとの関係など、参考になりましたら幸いです。 対象 今回は、NDLデジタルコレクションで公開されている以下のマニフェストファイルを対象にします。 https://dl.ndl.go.jp/api/iiif/3437686/manifest.json 変換 EASY RDF Converterを使用します。 https://www.easyrdf.org/converter 以下のように、IIIFマニフェストファイルのURLを指定して、Input FormatにJSON-LD、Output FormatにTurtleを指定します。 結果、以下のように変換されました。 @prefix ns0: <http://iiif.io/api/presentation/2#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . @prefix dc: <http://purl.org/dc/terms/> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix exif: <http://www.w3.org/2003/12/exif/ns#> . @prefix dc11: <http://purl.org/dc/elements/1.1/> . @prefix ns1: <http://rdfs.org/sioc/services#> . @prefix doap: <http://usefulinc.com/ns/doap#> . @prefix oa: <http://www.w3.org/ns/oa#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . <https://dl.ndl.go.jp/api/iiif/3437686/manifest.json> a <http://iiif.io/api/presentation/2#Manifest> ; ns0:attributionLabel "国立国会図書館 National Diet Library, JAPAN"^^xsd:string ; ns0:hasRanges ( <https://dl.ndl.go.jp/api/iiif/3437686/range/1> <https://dl.ndl.go.jp/api/iiif/3437686/range/2> <https://dl.ndl.go.jp/api/iiif/3437686/range/3> <https://dl.ndl.go.jp/api/iiif/3437686/range/4> <https://dl.ndl.go.jp/api/iiif/3437686/range/5> <https://dl.ndl.go.jp/api/iiif/3437686/range/6> <https://dl.ndl.go.jp/api/iiif/3437686/range/7> <https://dl.ndl.go.jp/api/iiif/3437686/range/8> <https://dl.ndl.go.jp/api/iiif/3437686/range/9> <https://dl.ndl.go.jp/api/iiif/3437686/range/10> <https://dl.ndl.go.jp/api/iiif/3437686/range/11> <https://dl.ndl.go.jp/api/iiif/3437686/range/12> <https://dl.ndl.go.jp/api/iiif/3437686/range/13> <https://dl.ndl.go.jp/api/iiif/3437686/range/14> <https://dl.ndl.go.jp/api/iiif/3437686/range/15> <https://dl.ndl.go.jp/api/iiif/3437686/range/16> ) ; ns0:hasSequences ( _:genid18 ) ; ns0:metadataLabels ( _:genid20 _:genid22 _:genid24 _:genid26 _:genid28 _:genid30 _:genid32 _:genid34 _:genid36 _:genid38 _:genid40 ) ; dc:rights <https://dl.ndl.go.jp/ja/iiif_license.html> ; rdfs:label "校異源氏物語. 巻一"^^xsd:string ; rdfs:seeAlso <https://dl.ndl.go.jp/api/oaipmh?verb=GetRecord&metadataPrefix=dcndl_porta&identifier=oai:dl.ndl.go.jp:info:ndljp/pid/3437686> ; foaf:logo <https://dl.ndl.go.jp/img/logo/ndldc/iiif-logo.png> . <https://dl.ndl.go.jp/api/iiif/3437686/range/1> a ns0:Range ; ns0:hasCanvases ( <https://dl.ndl.go.jp/api/iiif/3437686/canvas/3> ) ; rdfs:label "校異源氏物語 卷一"^^xsd:string . <https://dl.ndl.go.jp/api/iiif/3437686/canvas/3> a ns0:Canvas ; ns0:hasImageAnnotations ( _:genid43 ) ; rdfs:label "3"^^xsd:string ; exif:height 4706 ; exif:width 6890 . <https://dl.ndl.go.jp/api/iiif/3437686/range/2> a ns0:Range ; ns0:hasCanvases ( <https://dl.ndl.go.jp/api/iiif/3437686/canvas/19> ) ; rdfs:label "目次"^^xsd:string . <https://dl.ndl.go.jp/api/iiif/3437686/canvas/19> a ns0:Canvas ; ns0:hasImageAnnotations ( _:genid46 ) ; rdfs:label "19"^^xsd:string ; exif:height 4706 ; exif:width 6890 . ... RDF/XMLにも変換してみます。 ...

mirador-sync-windowsのMirador 4版のリポジトリを公開しました。

mirador-sync-windowsのMirador 4版のリポジトリを公開しました。

概要 以下の記事で、mirador-sync-windowsのMirador 4(3)版を作成したことを紹介しました。 今回は、本プラグインのリポジトリを公開したので、備忘録です。 リポジトリ 以下で公開しています。 https://github.com/nakamura196/mirador-sync-windows デモページ 以下からお試しいただけます。 https://nakamura196.github.io/mirador-sync-windows/ GitHub Pagesでの公開に向けて、設定した内容は以下です。 webpack 以下のファイルを一部変更しました。 https://github.com/nakamura196/mirador-sync-windows/blob/main/webpack.config.js 具体的には、以下です。publicPathについて、developmentの場合は、相対パスにしました。これにより、basePathによる問題に対処しました。 return { ...config, output: { filename: 'demo.js', path: path.join(__dirname, 'demo/dist'), // publicPath: '/' publicPath: options.mode === "development" ? './' : '/', }, devServer: { hot: true, port: 4444, static: [ './demo/dist/', ], }, devtool: 'eval-source-map', mode: 'development', entry: ['./demo/src/index.js'], plugins: [ ...(config.plugins || []), new HtmlWebpackPlugin({ template: path.join(__dirname, 'demo/src/index.html') }), new ReactRefreshWebpackPlugin(), ], }; GitHub Actions GitHub Actionsを使ったGitHub Pagesの利用にあたり、以下のようなymlファイルを用意しました。 テストがうまくいかず、その部分はコメントアウトしていますが、今後修正したいと思います。 https://github.com/nakamura196/mirador-sync-windows/blob/main/.github/workflows/node.js.yml まとめ 不完全な部分も多いですが、参考になりましたら幸いです。

Mirador 4プラグイン開発:任意の角度で画像を回転する

Mirador 4プラグイン開発:任意の角度で画像を回転する

概要 Mirador 4において、任意の角度で画像を回転するプラグインを作成しました。 https://github.com/nakamura196/mirador-rotation-plugin 以下で挙動をご確認いただけます。 https://nakamura196.github.io/mirador-rotation-plugin/ 背景 Mirador 3向けに本プラグインを開発していましたが、2024/3/15にMirador 4がプレリリースされました。 https://github.com/ProjectMirador/mirador/releases/tag/v4.0.0.alpha-1 Mirador 3の最新版であるv3.3.0は2021年のリリースだったため、使用されているライブラリ等も古くなっていましたが、今回の更新で、開発がしやすくなりました。 工夫 任意の角度で画像を回転するにあたり、Mirador 4をそのまま使うと、以下のように、角度の変更に対して、画像の回転が追いつかないケースがありました。 https://www.youtube.com/watch?v=zJKWCTA9rjw そこで以下の記事で述べたように、画像の回転や拡大・縮小を遅延なく行うための機能を追加したMiradorを使用しています。 具体的には、openseadragonのsetRotationなどで用意されているimmediatelyパラメータをMiradorから設定できるようにしました。 https://openseadragon.github.io/docs/OpenSeadragon.Viewport.html#setRotation ! 今回はMirador本体にも手を加えましたが、プラグイン側でこのような設定がすでにできるかもしれません。引き続き調査したいと思います。 参考 90度単位で画像を回転させるプラグインとしては、以下もあります。 https://github.com/ProjectMirador/mirador-image-tools こちらは回転だけでなく、さまざまな画像を操作を可能にします。 まとめ Miradorの利用にあたり、参考になりましたら幸いです。

カスタマイズしたMirador 4をnpmパッケージとして公開する

カスタマイズしたMirador 4をnpmパッケージとして公開する

概要 カスタマイズしたMirador 4をnpmパッケージとして公開する機会がありましたので、備忘録です。 Fork 以下の公式サイトからリポジトリをForkします。 https://github.com/projectmirador/mirador 以下のようになります。 ブランチを作成する クローンし、ブランチを作成します。 git clone https://github.com/nakamura196/mirador cd mirador git checkout -b feature-add-immediately-property 以下のように出力されます。 Switched to a new branch 'feature-add-immediately-property' 開発 以下で紹介したような改修を加えます。 テスト テストして、問題がないか確認します。 pnpm test コミット git add . git commit -a -m "feat: add immediately property" マージ masterブランチに戻って、feature-add-immediately-propertyの内容をマージする git checkout master git merge feature-add-immediately-property push masterブランチの変更内容をpushしておきます。 git push publish 以下のコマンドにより、ローカルの変更を一時的に無視するようにします。(他に良い方法がありそうです…) git update-index --assume-unchanged package.json パッケージ名を別名に変更します。 { "name": "@nakamura196/mirador", "version": "4.0.0-alpha.3", "description": "An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", "files": [ "dist" ], "sideEffects": false, ... publishします。 ...

Mirador 4の拡大・縮小・回転の挙動を確認する

Mirador 4の拡大・縮小・回転の挙動を確認する

概要 Mirador 4の拡大・縮小・回転の挙動を変更する必要があり、その変更方法に関する備忘録です。 セットアップ 以下により、ローカルでMirador 4を起動します。 git clone https://github.com/projectmirador/mirador cd mirador pnpm i pnpm start ポート4444で起動します。 zoomIn時の処理のカスタマイズ 一例ですが、zoomInボタンをクリックした際の処理を以下のように変更してみます。 ... handleZoomInClick() { const { windowId, updateViewport, viewer } = this.props; updateViewport(windowId, { // zoom: viewer.zoom * 2, zoom: viewer.zoom * 1.1, // 追加 rotation: viewer.rotation + 5, // 追加 x: viewer.x * 1.1, // 追加 y: viewer.y * 1.1, // 追加 }); } ... 結果、zoomInボタンを押した際に、中心が少しずれながら、拡大・回転が行われることがわかります。 https://youtu.be/wn1WxpTVpS4 これを応用することで、Mirador 3の拡大・縮小・回転等のカスタマイズを行うことができます。 immediateの設定 上記の例では、拡大や回転が完了するまで少し時間がかかっていました。これを即座に行いたい場合、以下のOpenSeadragonViewer.jsのcomponentDidUpdateをカスタマイズします。 viewerConfigオブジェクトのimmediatelyプロパティに基づき、拡大縮小や回転を即座に実施するかを設定できるようにします。 ... componentDidUpdate(prevProps, prevState) { const { viewerConfig, canvasWorld, } = this.props; const { viewer } = this.state; this.apiRef.current = viewer; if (prevState.viewer === undefined) { if (viewerConfig) { viewer.viewport.panTo(viewerConfig, true); viewer.viewport.zoomTo(viewerConfig.zoom, viewerConfig, true); viewerConfig.degrees !== undefined && viewer.viewport.setRotation(viewerConfig.degrees); viewerConfig.flip !== undefined && viewer.viewport.setFlip(viewerConfig.flip); } this.addAllImageSources(!(viewerConfig)); return; } if (!this.infoResponsesMatch(prevProps.infoResponses) || !this.nonTiledImagedMatch(prevProps.nonTiledImages) ) { viewer.close(); const canvasesChanged = !(isEqual(canvasWorld.canvasIds, prevProps.canvasWorld.canvasIds)); this.addAllImageSources((canvasesChanged || !viewerConfig)); } else if (!isEqual(canvasWorld.layers, prevProps.canvasWorld.layers)) { this.refreshTileProperties(); } else if (viewerConfig && !this.osdUpdating) { const { viewport } = viewer; const immediately = viewerConfig.immediately || false; if (viewerConfig.x !== viewport.centerSpringX.target.value || viewerConfig.y !== viewport.centerSpringY.target.value) { viewport.panTo(viewerConfig, immediately); } if (viewerConfig.zoom !== viewport.zoomSpring.target.value) { viewport.zoomTo(viewerConfig.zoom, viewerConfig, immediately); } if (viewerConfig.rotation !== viewport.getRotation()) { viewport.setRotation(viewerConfig.rotation, immediately); } if (viewerConfig.flip !== viewport.getFlip()) { viewport.setFlip(viewerConfig.flip); } } } ... そして、先のZoomControls.jsにおいて、immediately: trueを追加します。 ...

zenodoで資料を公開する

zenodoで資料を公開する

概要 zenodoの使い方を学ぶにあたり、資料を登録してみましたので、備忘録です。登録した資料に付与されたDOIは以下です。 https://zenodo.org/doi/10.5281/zenodo.12508032 DOI DOIについては、最新のバージョンにアクセスできるものと、各バージョンに付与されるものがあり、上記のDOIは前者の者です。バージョン1は以下です。 https://zenodo.org/doi/10.5281/zenodo.12508033 バージョンについては、以下の記事も参考にしてください。 バージョン ファイルの追加や更新を行わない限り、バージョンを変更する必要はなさそうでした。PDFをアップロードした際にDOIが付与され、その後にメタデータを編集しても、バージョンに変更はありませんでした。 このメタデータの更新については、画面右下の「Technical metadata」で確認できました。バージョン1が作成されたのは6/23ですが、6/24に更新されていることが確認できます。 エクスポート JSON-LD いくつかのフォーマットでエクスポートできますが、JSON-LDによる出力もサポートされていました。 { "@context": "http://schema.org", "@id": "https://doi.org/10.5281/zenodo.12508033", "@type": "https://schema.org/PresentationDigitalDocument", "identifier": "https://doi.org/10.5281/zenodo.12508033", "name": "AIPを作成・利用するツール紹介", "creator": [ { "name": "Nakamura, Satoru", "givenName": "Satoru", "familyName": "Nakamura", "affiliation": [ { "@type": "Organization", "name": "The University of Tokyo" } ], "@id": "https://orcid.org/0000-0001-8245-7925", "@type": "Person" } ], "author": [ { "name": "Nakamura, Satoru", "givenName": "Satoru", "familyName": "Nakamura", "affiliation": [ { "@type": "Organization", "name": "The University of Tokyo" } ], "@id": "https://orcid.org/0000-0001-8245-7925", "@type": "Person" } ], "publisher": { "@type": "Organization", "name": "Zenodo" }, "datePublished": "2024-06-23", "dateModified": "2024-06-24T01:00:09.177651+00:00", "temporal": [ "2024-06-21" ], "inLanguage": { "alternateName": "jpn", "@type": "Language", "name": "Japanese" }, "contentSize": "2.47 MB", "size": "2.47 MB", "license": "https://creativecommons.org/licenses/by/4.0/legalcode", "url": "https://zenodo.org/records/12508033" } これをEASY RDF ConverterでRDF/XMLに変換した結果は以下です。schema.orgを中心に使用されていることがわかります。 ...

Mirador 2のプラグインの挙動を確認する

Mirador 2のプラグインの挙動を確認する

概要 Mirador 2のプラグインの挙動を確認するリポジトリを作成しました。 https://github.com/nakamura196/mirador2-plugins-demo 以下のURLからお試しいただけます。 https://nakamura196.github.io/mirador2-plugins-demo/ サンプルデータを含む動作例は以下です。 https://nakamura196.github.io/mirador2-plugins-demo/?manifest=https://nakamura196.github.io/mirador2-sync-windows/data/examples/org.json;https://nakamura196.github.io/mirador2-sync-windows/data/examples/inf.json 本リポジトリを作成した目的は、Mirador 2向けに開発されたプラグインをMirador 3向けに改修するための挙動確認です。 プラグイン mirador-sync-windows 以下の記事で紹介したmirador-sync-windowsを有効にしています。 こちらについては、以下の記事でM3版を試作しています。 mirador-disable-plugin UCLA LibraryによってMirador 2向けに作成された以下のプラグインを有効にしています。 https://github.com/UCLALibrary/mirador-disable-zoom こちらについても、以下の記事でM3版を作成しています。 https://youtu.be/RN2V4b7IYoI まとめ Mirador 2のプラグインの挙動確認にあたり、参考になりましたら幸いです。引き続き、プラグインの追加などを行いたいと思います。

ズーム操作を無効化するMirador 3(4)向けプラグインの開発

ズーム操作を無効化するMirador 3(4)向けプラグインの開発

概要 Mirador 3(実際には、Mirador 4)向けに、ズーム操作を無効化するプラグインを作成しました。 https://github.com/nakamura196/mirador-disable-zoom/ 以下が動作デモです。 https://youtu.be/RN2V4b7IYoI 以下のURLからお試しいただけます。 https://nakamura196.github.io/mirador-disable-zoom/ 本プラグインは、UCLA LibraryによってMirador 2向けに作成された以下のプラグインを参考にしています。 https://github.com/UCLALibrary/mirador-disable-zoom 今回は、本プラグインの開発によって気がついた点をメモします。 targetの指定 targetによって、プラグインのボタンを設置する場所を指定することができました。今回は、WindowTopBarPluginAreaを指定することで、ウインドウ毎のバーに直接アイコンを表示することができました。 import * as actions from 'mirador/dist/es/src/state/actions'; import { getWindowConfig } from 'mirador/dist/es/src/state/selectors'; import MiradorDisableZoom from './plugins/MiradorDisableZoom'; import MiradorDisableZoomMenuItem from './plugins/MiradorDisableZoomMenuItem'; import translations from './translations'; export const miradorDisableZoomPlugin = [ { target: 'OpenSeadragonViewer', mode: 'add', component: MiradorDisableZoom, mapStateToProps: (state, { windowId }) => ({ enabled: getWindowConfig(state, { windowId }).disableZoomEnabled || false, }) }, { target: 'WindowTopBarPluginArea', component: MiradorDisableZoomMenuItem, mode: 'add', mapDispatchToProps: { updateWindow: actions.updateWindow, }, mapStateToProps: (state, { windowId }) => ({ enabled: getWindowConfig(state, { windowId }).disableZoomEnabled || false, }), config: { translations, }, }, ]; https://github.com/nakamura196/mirador-disable-zoom/blob/main/src/index.js 一方、以下の記事で紹介したプラグインでは、WindowTopBarPluginMenuを指定しています。 この場合には、以下のように、3点ドットのメニューが表示され、その中にプラグイン毎のアイコンなどを表示できました。 用途に応じて、targetを使い分けることができそうです。 これらのtargetは以下で指定されているコンポーネントを使用できるようでした。 https://github.com/ProjectMirador/mirador/tree/master/src/containers translations 上記のコードにおいて、config属性のtranslationsを指定しています。 { target: 'WindowTopBarPluginArea', component: MiradorDisableZoomMenuItem, mode: 'add', mapDispatchToProps: { updateWindow: actions.updateWindow, }, mapStateToProps: (state, { windowId }) => ({ enabled: getWindowConfig(state, { windowId }).disableZoomEnabled || false, }), config: { translations, }, }, 上記を指定しないと、同フォルダ内のtranslations.jsで指定した翻訳データが反映されませんでした。 ...

iiif-prezi3を試す

iiif-prezi3を試す

概要 IIIF Presentation API 3が普及しつつありますが、その仕様を理解しつつ、JSONファイルを直接作成することが難しく感じるようになりました。 そこで、以下のPythonライブラリを使用してみましたので、備忘録です。 https://github.com/iiif-prezi/iiif-prezi3 以下の記事で紹介した東寺百合文書WEBで公開されているデータのIIIFへの変換にあたり、本ライブラリを使用しています。 読みにくいもので恐縮ですが、ソースコードも以下のリポジトリで公開していますので、参考になりましたら幸いです。 https://github.com/nakamura196/toji_iiif コレクションの作成 以下のようなコードにより、IIIFコレクションを作成できました。 import iiif_prezi3 iiif_prezi3.config.configs['helpers.auto_fields.AutoLang'].auto_lang = "ja" collection = iiif_prezi3.Collection( id=f"{origin}/set/3/collection.json", label="東寺百合文書", viewingDirection="right-to-left", provider=iiif_prezi3.ProviderItem( id=self.homepage, label=self.attribution, ), homepage=iiif_prezi3.HomepageItem( id=self.homepage, type="Text", label=self.attribution, format="text/html", language="ja" ), metadata=[ iiif_prezi3.KeyValueString(label="Attribution", value=self.attribution), iiif_prezi3.KeyValueString(label="Rights", value=self.rights), ], rights=self.rights, ) opath = f"{self.docs_dir}/iiif/set/3/collection.json" os.makedirs(os.path.dirname(opath), exist_ok=True) with open(opath, "w") as f: f.write(collection.json(ensure_ascii=False, indent=2 if IS_DEBUG else None)) iiif_prezi3.config.configs['helpers.auto_fields.AutoLang'].auto_langにjaを与えることで、labelやmetadataの言語フィールドがjaになりました。 { "@context": "http://iiif.io/api/presentation/3/context.json", "id": "https://nakamura196.github.io/toji_iiif/iiif/set/3/collection.json", "type": "Collection", "label": { "ja": [ "東寺百合文書" ] }, "metadata": [ { "label": { "ja": [ "Attribution" ] }, "value": { "ja": [ "京都府立京都学・歴彩館 東寺百合文書WEB" ] } }, { "label": { "ja": [ "Rights" ] }, "value": { "ja": [ "https://creativecommons.org/licenses/by/2.1/jp/" ] } } ], "rights": "https://creativecommons.org/licenses/by/2.1/jp/", "provider": [ { "id": "https://hyakugo.pref.kyoto.lg.jp/", "type": "Agent", "label": { "ja": [ "京都府立京都学・歴彩館 東寺百合文書WEB" ] } } ], "homepage": [ { "id": "https://hyakugo.pref.kyoto.lg.jp/", "type": "Text", "label": { "ja": [ "京都府立京都学・歴彩館 東寺百合文書WEB" ] }, "format": "text/html", "language": [ "ja" ] } ], "items": [ { "id": "https://nakamura196.github.io/toji_iiif/iiif/3/1/manifest.json", "label": { "ja": [ "イ函/1/:山城国紀伊郡司解案" ] }, "type": "Manifest" } ] } iiif_prezi3.KeyValueString関数を使用することで、フィールドや値が配列として出力される点も有用かと思いました。 ...