iOS18のHEIC画像は古いImageMagickだと読めない
zennでは1ツイートにぎゅうぎゅうに詰め込んだ技術的な話のもうちょっと詳しい話を書いていきます。今日はこれです。
最近、プライベートの時間ではHugoをいろいろいじってて、テーマとかShortcodeをいろいろいじってるとよくできた仕組みだなあと感心しています(近況)。
それはさておき、iPhoneで写真を撮ると、結構前からHEICというファイル形式で保存されるようになりました。JPEGとかよりも画質がよくて圧縮率も高いらしいです。
ただ、HEICな画像は <img src="powawa.HEIC" alt="ぽわわ"/>
のように書いてもたいていのブラウザでは表示できません。caniuseで調べてみると、一応Safari 17からだけサポートされているようです。
ということで、最終的にwebpとかにしていくにしても、一旦jpegとかにしちゃったほうが取り回しがよいので、HEICをJPEGに変換するワンライナーを書いてTaskfileに設定しています。
convert:
cmds:
- convert {{ .CLI_ARGS }} -sampling-factor 4:2:0 -quality 85 -interlace JPEG -colorspace sRGB `echo {{ .CLI_ARGS }} | sed s/HEIC/jpeg/`
- rm {{ .CLI_ARGS}}
こんな感じのを書いておくと、
$ task convert -- path/to/image.HEIC
task: [convert] convert path/to/image.HEIC -sampling-factor 4:2:0 -quality 85 -interlace JPEG -colorspace sRGB `echo path/to/image.HEIC | sed s/HEIC/jpeg/`
task: [convert] rm path/to/image.HEIC
みたいな感じで画像を変換して path/to/image.jpeg
ファイルが出来上がります。
HEICからJPEGに変換できないファイルがある
で、めでたいめでたいと思っていたのですが、今日実行したらなんかエラーになってしまいました。
convert-im6.q16: no images defined `path/to/image.jpeg' @ error/convert.c/ConvertImageCommand/3229.
エラーメッセージが親切ではなさすぎる。とりあえず出力ファイル側に問題ありそう? とおもってディレクトリのパーミッションとかも見ましたが、特に問題なし。
とりあえず検索してみますが、見つかるのは /etc/ImageMagick-6/policy.xml
の制限に引っかかってると思うよ、みたいな話くらいです。典型的なのはwidth/heightが10000ピクセル以上あると10KPのポリシーに引っかかるという話らしいのですが、お手元の画像は4032x3024だし、ポリシーは16KPになってるのでこの辺の話ではなさそう。
で、convert
コマンドには -debug
というオプションがあるので、-debug All
としてエラーの原因を調べます。最後の5行くらいを抜粋するともうちょっと詳しい状況がわかりました。
0:00.027 0.000u 6.9.11 Exception convert-im6.q16[2725308]: heic.c/IsHeifSuccess/119/Exception
Invalid input: Unspecified: Too many auxiliary image references `path/to/image.HEIC'
0:00.027 0.000u 6.9.11 Cache convert-im6.q16[2725308]: cache.c/DestroyPixelCache/1191/Cache
destroy
0:00.029 0.000u 6.9.11 Resource convert-im6.q16[2725308]: resource.c/RelinquishMagickResource/1259/Resource
Map: 1.59123MB/0B/512MiB
0:00.029 0.000u 6.9.11 Exception convert-im6.q16[2725308]: convert.c/ConvertImageCommand/3229/Exception
no images defined `path/to/image.jpeg'
convert-im6.q16: no images defined `path/to/image.jpeg' @ error/convert.c/ConvertImageCommand/3229.
Invalid input: Unspecified: Too many auxiliary image references
ということはやっぱり出力ファイル側じゃなくて入力側の問題ですかね。このメッセージで検索するとそれっぽいIssueがみつかりました。
とりあえずiOS18のHEIFはフォーマットがちょっと変わって読めなくなってたようで、libheif 1.18以上にあげればOKということのようです。たしかに、今まで昔のHEIC画像しか変換してなかったので最近iOS18になってからの写真を変換するのは初めてなのでした。
bookwormでlibheifを1.18以降に上げる
私の実行環境はDebian 12 (bookworm)です。検索してみると、bookwormのlibheifは1.15のようです。
bookworm-backportsには1.19が来ているので、これに切り替えればよさそう。
/etc/apt/sources.list
にbackportsを追加します。
deb http://ftp.jp.debian.org/debian bookworm-backports main contrib non-free non-free-firmware
apt updateして、libheifのShared Libraryである、libheif1
パッケージを入れ換えます。
# apt update
# apt install -t bookworm-backports libheif1
Get:1 http://ftp.jp.debian.org/debian bookworm-backports/main amd64 libheif-plugin-dav1d amd64 1.19.3-1~bpo12+1 [11.3 kB]
Get:2 http://ftp.jp.debian.org/debian bookworm-backports/main amd64 libheif-plugin-libde265 amd64 1.19.3-1~bpo12+1 [15.1 kB]
Get:3 http://ftp.jp.debian.org/debian bookworm-backports/main amd64 libheif1 amd64 1.19.3-1~bpo12+1 [454 kB]
Get:4 http://ftp.jp.debian.org/debian bookworm-backports/main amd64 libheif-plugin-aomenc amd64 1.19.3-1~bpo12+1 [21.4 kB]
Get:5 http://ftp.jp.debian.org/debian bookworm-backports/main amd64 libheif-plugin-x265 amd64 1.19.3-1~bpo12+1 [22.3 kB]
途中で流れるメッセージで、ちゃんとbackportsから1.19系を取ってきてる事も確認できました。
libheif1
を入れ換えた後にもう1回convertコマンドで画像変換を試みたところ、無事以前のように変換できました。めでたしめでたし。
Discussion