概要
Omeka SのIIIF Serverモジュールで、PLYファイルがIIIFマニフェストのitemsとして出力されないが、GLBファイルは正常に出力される問題を調査しました。

前提条件:Omeka Sの設定
デフォルトでは、PLYファイルはOmeka Sにアップロードできません。以下の設定が必要です。
PLYファイルアップロード時のエラー

デフォルト設定では、PLYファイルのメディアタイプ(application/octet-stream)と拡張子(.ply)が許可されていないため、アップロードエラーが発生します。
設定の追加
管理画面の「設定」→「セキュリティ」で以下を追加してください:

- 許可されるメディアタイプ :
application/octet-streamを追加 - 許可されるファイル拡張子 :
plyを追加
原因
PLYファイルの処理コードがモジュールに実装されていませんでした。
GLBファイルには明示的な拡張子チェックと型変換のコードが存在しますが、PLYファイルには同様のコードが存在しませんでした。
技術的詳細
GLBファイルの処理(修正前から存在)
TraitMedia.php (format()メソッド)
if ($mediaType === 'application/octet-stream') {
$extension = strtolower(pathinfo((string) $this->resource->source(), PATHINFO_EXTENSION));
if ($extension === 'glb') {
return 'model/gltf-binary';
}
}
IiifTypeOfMedia.php
if ($mediaType === 'application/octet-stream') {
$extension = strtolower(pathinfo((string) $media->source(), PATHINFO_EXTENSION));
if ($extension === 'glb') {
return $mediaIiifTypes[$mediaId] = 'Model';
}
}
IIIFマニフェストのitems生成フロー
メディアタイプの判定 (
TraitMediaInfo.php)- 各メディアをIIIFタイプ(Image, Video, Sound, Text, Dataset, Model, other, invalid)に分類します
Painting候補の優先付け
- 優先度順: Model > Video > Sound > Image > Text
Modelタイプは最優先でCanvasのpaintingに選ばれます
Canvasへの配置 (
Manifest.php)
foreach ($this->resource->media() as $media) {
$mediaInfo = $this->mediaInfo($media);
if ($mediaInfo && !empty($mediaInfo['painting'])) {
// Canvasを作成してitemsに追加
}
}
PLYがitemsに含まれなかった理由
- PLYファイルがアップロードされると、メディアタイプは
application/octet-streamになることが多いです - 拡張子
.plyをチェックするコードが存在しませんでした - IIIFタイプが
Modelとして認識されず、otherまたはinvalidに分類されました paintingキーが設定されないため、Canvasが生成されませんでした
修正内容
1. src/Iiif/TraitMedia.php
if ($mediaType === 'application/octet-stream') {
$extension = strtolower(pathinfo((string) $this->resource->source(), PATHINFO_EXTENSION));
if ($extension === 'glb') {
return 'model/gltf-binary';
} elseif ($extension === 'ply') {
return 'model/ply'; // 追加
}
}
2. src/View/Helper/IiifTypeOfMedia.php
if ($mediaType === 'application/octet-stream') {
$extension = strtolower(pathinfo((string) $media->source(), PATHINFO_EXTENSION));
if ($extension === 'glb') {
return $mediaIiifTypes[$mediaId] = 'Model';
} elseif ($extension === 'ply') {
return $mediaIiifTypes[$mediaId] = 'Model'; // 追加
}
}
修正後の動作
PLYファイル(拡張子.ply)がapplication/octet-streamとして認識された場合:
- メディアタイプが
model/plyとして返されます - IIIFタイプが
Modelとして認識されます - GLBファイルと同様にIIIFマニフェストの
itemsに出力されます
出力例
修正後、PLYファイルを含むアイテムのIIIFマニフェストは以下のように出力されます:
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "http://localhost/iiif/3/3/manifest",
"type": "Manifest",
"label": {
"none": [
"cactus"
]
},
"items": [
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "http://localhost/iiif/3/3/canvas/p1",
"type": "Canvas",
"label": {
"none": [
"1"
]
},
"items": [
{
"id": "http://localhost/iiif/3/3/annotation-page/4",
"type": "AnnotationPage",
"items": [
{
"id": "http://localhost/iiif/3/3/annotation/4",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "http://localhost/files/original/549653c63ab23c880e4625fa3b6dae46a817b9b2.ply",
"type": "Model",
"format": "model/ply"
},
"target": "http://localhost/iiif/3/3/canvas/p1"
}
]
}
]
}
]
}
items内にCanvasが生成され、bodyのtypeがModel、formatがmodel/plyとして出力されています。
関連ファイル
| ファイル | 役割 |
|---|---|
src/Iiif/TraitMedia.php | メディアフォーマット(MIMEタイプ)の判定 |
src/View/Helper/IiifTypeOfMedia.php | IIIFタイプ(Image, Model等)の判定 |
src/Iiif/TraitMediaInfo.php | メディア情報の収集とpainting候補の選択 |
src/Iiif/Manifest.php | IIIFマニフェストのitems生成 |
謝辞
本調査で使用したPLYファイルのサンプルデータは、以下の記事からダウンロードさせていただきました:
- 【ダウンロード可】3Dガウシアン スプラッティング データ(PLY) - steam studio / 3D SCAN STUDIO iris
調査日
2026-02-06