はじめに
前回では Elixir で VRM をパースして画像一覧を取得しました。
今回 VRM の Meta 情報を読んでサムネイルを取得しようと思います。
VRM の Meta 情報
VRM の "images"
の中にはファイル名の情報がありますが、どれがサムネイル画像かの情報はありません。Vroid Studio で作成した VRM は自動的にサムネイルのファイル名が thumbnail.png
になりますが、Vroid Studio 以外で作られたファイルに対応出来ません。そのため、VRM の Meta 情報を読む必要があります。
alicia_data["images"]
glb は "extensions" の下に拡張して定義している情報を置けるようになっています。VRM 0.x の場合、ここに VRM
という形で拡張情報を保存しています。また、VRM 1.0 以降の場合、VRM
ではなく"VRMC_vrm"
という形で拡張情報を保存します。
それぞれ保存できる内容は Json Schema にて定義されています。
メタ情報は VRM0.x と VRM1.0 で中身は異なるのですが、作者の情報やライセンスに加え、サムネイル画像に関する情報も保存してあります。この情報は "images"
の中でサムネイル画像がどれなのかの index 番号になります。
Meta のサムネイルの index 番号に関する情報は VRM0.x の場合 texture
、VRM1.0 の場合thumbnailImage
に保存されています。
https://github.com/vrm-c/vrm-specification/blob/master/specification/0.0/README.md#thumbnail
https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/meta.md
サムネイル画像の取得
case を使って images
の index を探します。
thumbnail_index =
case alicia_data do
%{"extensions" => %{"VRM" => vrm}} ->
get_in(vrm, ["meta", "texture"])
%{"extensions" => %{"VRMC_vrm" => vrm}} ->
get_in(vrm, ["meta", "thumbnailImage"])
end
images の中からサムネイルの index 番号を使ってサムネイル画像を特定し表示してみます。
%{"bufferView" => index, "mimeType" => mime_type, "name" => name} = Enum.at(images, thumbnail_index)
%{"byteOffset" => offset, "byteLength" => length} = Enum.at(buffer_views, index)
<<_::size(offset)-bytes, content::size(length)-bytes, _::bits>> = binary_chunk_data
%Kino.Image{content: content, mime_type: mime_type}
Kino.Download.new/2 を使うことでサムネイル画像をダウンロードすることも可能です。
Kino.Download.new(fn -> content end, filename: "#{name}.png")