Linux

Slackware -currentでHEIC対応のdigiKamを動かす

写真管理のソフトウェアを、macOSの写真アプリから、KDEのdigiKamに移行しました。その際に、HEIC画像を扱うことができなかったので対処をした際のログです。

TL;DR

Slackware -currentのImageMagick (7.1.2-7)は --with-heic=yes でコンパイルされていないため、それを使っているdigiKamでもHEIC/HEIFフォーマットの画像を扱うことができない。同じ理由で、Gwenviewでも扱うことができない。

そもそもの発端

つい最近までDebian GNU/Linuxを使っていたのですが、思うところがありここ数日でSlackware -currentに環境を移行しました。kernel/gcc/emacsを自前でコンパイルし、色々な試行錯誤を繰り返しながら、なんとか必要な作業ができるようになってきたことから、本格的にデータを移行することにしました。

これといった理由は特に無いのですが、趣味の写真をさっさと再開できるようにということで、まずは写真のデータをSlackwareに移行することにしました。

HEICフォーマットの画像がdigiKamに表示されない

HEICフォーマットはiPhone等で使われる形式で、同程度の視覚品質を得るためにはJPEGの50-60%程度のファイルサイズで済むといわれています。つまり、容量に制約のあるスマートフォンや、クラウドサービスの容量を節約したい場合にHEICを使うことが良いのではないかと思われます。私も、iPhoneでHEICが使われるようになってからというもの、iPhoneで撮る写真はすべてHEIC形式になりました。

それらの写真をdigiKamに取り込もうとした時に、サムネイルもプレビューも表示されないので「どうなってんだ?」と思い調査したところ、まず判ったのは libheif がシステムにインストールされていないことでした。

libheif をインストールする

libheiflibaomlibde265 に依存している。まずはそれらをシステムにインストールする必要があるので、準備する。 libaomdarkskygit / libaomから入手することができる。また libde265structurag / libde265から入手できるので、それぞれREADMEを参考にコンパイルしてパッケージを作り installpkg でインストールしておく。

次に libheif をインストールする。 libheifstructurag / libheifから入手できるので、こちらもREADMEを参考にコンパイルしてパッケージを作り installpkg でインストールしておく。途中 /usr/lib64/libaom.a が見付からないというエラーが出るので ln -s /usr/lib64/libaom.a /usr/local/lib64/libaom.a としてsymlinkを張っておく。

ここまで実施してdigiKamを起動しても状況は変わらなかった。なぜだと考え、調べているうちに、どうやらdigiKamはバックエンドにImageMagickを使っていそうだということがわかり、では、ImageMagickでHEIC/HEIFは有効になっているのだろうかと調べたところ有効になっていなかったのであった。

$ magick -list format | grep HEIC    # 結果は何も表示されなかった => 無効
$ magick -list format | grep HEIF    # 結果は何も表示されなかった => 無効

ImageMagickを --with-heic=yes つきでインストールする

ImageMagicは、currentのソースコードをもとにコンパイルする。 imagemagic.SlackBuild の中に記載されている ./configure に対し --with-heic=yes を指定したうえでパッケージを作成し、インストールする。

Debian GNU/Linux 13 (trixie)の4K出力が安定しない件を解決する

Debian GNU/Linux 13 (trixie)とThinkPad E14 (Gen 3)で、外部モニター(JapanNext)への4K出力が安定しなかったので対処しました。

私は普段、Debian GNU/Linux 13 (trixie)をThinkPad E14 (Gen 3)で運用しており、外付けモニターとしてJapanNextの4Kモニターを使用しています。4K出力に対応しておりながら安価である点が気に入っています。

さて、その環境も、HDMI出力が安定せず、画面が表示されたりされなかったりで作業にならない状況が続いていました。どうもXがEDIDをモニターから取得するまでのタイムラグが原因のように思えましたので、環境決め打ちになってしまうのが気にはなりますが、以下のように対処をしました。

ここに記述している内容はX向けの設定ですが、結果的にXWayland経由で設定が反映されていることになります。

問題の切り分け

まずは物理的な問題を除外しました。

モニター自体は正常か?
手元にあるMacBookを使ったところ正常に4K出力できたので、問題は無いと判断した。
HDMIケーブル自体は正常か?
手元にあるMacBookに接続してみたところ正常に4K出力できたので、問題は無いと判断した。
ThinkPadのHDMIポートに問題は無いか?
手元にある他のモニター(FullHD)に接続してみたところ正常に出力できたので、問題は無いと判断した。

この結果、物理的なハードウェアの問題ではなく、モニターとThinkPadの間の通信(ネゴシエーション)がうまくいかない場合がある、という仮説にいたりました。

ネゴシエーションの肝となる EDID (Extended Display Identification Data: 拡張ディスプレイ識別データ)

EDIDは、モニターが自分自身の仕様をコンピュータに伝えるデータです。具体的には以下の情報を含みます。

  • 対応解像度(例:1920x1080、3840x2160)
  • リフレッシュレート(例:60hz)
  • 色深度やカラーフォーマット
  • 製造情報
  • タイミング情報(垂直/水平同期)

通常、コンピュータはEDIDを参照して自動的に最適な解像度やリフレッシュレートを設定します。EDIDのやり取りが失敗すると、画面が表示されなかったり、 xrandrBadMatch エラーを返したりします(追記:これは、Waylandで実行すると出るエラーです)。

モニターから取得したEDID情報をXWayland経由で読み込む

つまり、モニターとやり取りをして解像度等を決定するのではなく、あらかじめEDIDを取得しておき、それをXから読み取るようにしておけば、ネゴシエーションに失敗する可能性は低いわけです。ただ問題は、EDIDを取得するためにはきちんと画面出力されている必要があるということで、そこまではなんとかする必要があるということです。全く表示されない場合には、この手段は使えないと思います。

EDIDを取得する

/sys/class/drm/card0-HDMI-A-1/edid からダンプしておきます。ここは環境に依存しますので、どのパスからダンプすればよいのかは xrandr の情報を参考にして決めてください。

$ sudo mkdir -p /etc/X11/edid/
$ sudo cat /sys/class/drm/card0-HDMI-A-1/edid > /etc/X11/edid/JAPANNEXT_JN-280IPS4KR.bin

Xの設定

/etc/X11/xorg.conf.d/10-monitor.conf を編集します。

Section "Monitor"
   Identifier "HDMI-1"
   Option "CustomEDID" "HDMI-1:/etc/X11/edid/JAPANNEXT_JN-280IPS4KR.bin"
EndSection

ゴミデータの削除

~/.config/monitors.xml が悪さをする可能性があるので、消しておきます。

Debian GNU/Linux 13 (trixie)でSwiftを動かす

Debian GNU/LinuxでSwiftを動かしてみようという試みをしました。

Swift は、Apple社が開発をしているプログラミング言語で、主にApple製品で動作させるソフトウェアを開発するために使用されるものですが、オープンソース化されてからというもの、Linuxなどサーバサイドで動作するソフトウェアの開発にも使われているようです。

今回は、たまたま目新しいということで、インストールしてみました。

Swiftをインストールする

Install Swiftを参考にすればインストール自体は簡単にできます。

$ cd
$ mkdir swiftly
$ cd swiftly
$ curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz
$ tar xvzf swiftly-$(uname -m).tar.gz
$ sudo ./swiftly init --quiet-shell-followup
$ sudo apt install libstdc++-12-dev     # Swiftlyからインストールを求められた場合のみ
$ . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh"
$ hash -r

~/.bashrc にも、以下を追記しておきます。

# Swift
. "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh"
hash -r

Hello World してみる

swift にパスが通っていることを前提に、以下のコマンドを実行します。

$ mkdir helloworld
$ cd helloworld
$ swift package init --name HelloWorld --type executable
$ swift run HelloWorld

すると、以下のように実行されます。初回はとにかく遅く、Hello Worldだけにも関わらず約5秒の処理時間が掛っていました。