Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

さまざまな色覚特性のもとで画像がどう見えるかをモンタージュする

こういう画像を吐き出してくれるシェルスクリプトを組んだ:

さまざまな色覚特性のもとでどう画像が見えるかを1枚にモンタージュした画像

このスクリプトの利点として以下を挙げたい:

  • OS上で直接画像が得られる
  • 1枚の画像が得られるため比較しやすい
  • 高速に動作する

ただし欠点もある:

  • コードは非-商用利用での利用に限られる

スクリプトは末尾に置いてあるので、説明に興味が無い人は途中まで飛ばしてください。

公私ともに1Passwordのオートフィルにかなり頼っていたり、また会社でアクセシビリティについて会話するSlackチャンネルである #accessibility が活発に活動していたりと、身の回りでアクセシビリティ(accessibility, a11y)を意識することが増えてきた。なんで1Passwordがアクセシビリティに関係するのかというと、1PasswordはHTML上のフォームの属性をかなり細かく見ていて、どのフィールドに何をフィルしていいかを判定しているため、広い意味ではアクセシビリティ的な技術に入ると考えているためだ。

www.mizdra.net

きちんとフィールドに属性が入っていれば、ブラウザはそれに応えてくれる。

色覚特性とは

さて、色覚特性*1というのがあって、特定の色が見えにくかったりするという人がいる。英語ではcolor blindnessと呼ぶらしい。

en.wikipedia.org

男性の数%はこの特性を保有しているという。

なんで画像のアクセシビリティが気になったのかというと、先日Zstandardという圧縮技術の記事を書いたのだが:

blog.3qe.us

このグラフって本当に視覚を使える全ての人にとって見易いのかな、ということが気になってきたためである。

もちろん、視覚を使える全ての人にとってわかりやすいグラフになっていることが望ましい。

Peacockを使って色覚特性にもとづく見え方を確認する(なぜ既存のツールが使えないか)

いちおう、色覚特性に基いてページを表示してくれるChrome拡張機能とか、さまざま色覚のもとで画像がどう見えるかをオンラインで確認できるサイトなどがあるが、以下のような使い勝手の悪さを感じていた:

  • 仕事で使っている成果物を、他人のサイトにアップロードするわけにはいかない
  • Chrome拡張は一度に1つの特性による見え方しか確認できない
  • Chrome拡張はDOMの見え方を修正するだけなので、その様子を他人に共有するためにはスクショなどが必要である

そこで、直接OSの上で画像を変換できる既存のオープンな実装を探してみたところ、以下のOSSを発見できた:

github.com

このOSSを使って、画像を生成してみることにした。

ただし、以下のライセンス条項がある:

The conversion processes and coefficients herein are used with permission from Colblindor and were therein used with permission of Matthew Wickline and the Human-Computer Interaction Resource Network for non-commercial purposes. As such, this code may only be used for non-commercial purposes.

非商用利用に限って使うことができるとのことだ。「この画像はどう見えるかな〜」と業務時間中に確認するのは、どっちになるのか気になる。非商用利用の境目は難しい。

Peacockのインストール

PeacockにはC++版とPython版とがあり、別にどちらを使っても良いのだが、今回はC++版を使うことにする。C++版のインストールのために、以下のようなソフトウェアやライブラリが必要となる:

  • libMagick++ とそのヘッダファイル(たいていのディストリビューションでlibMagick++-develといった名前になっているはず)
  • CMake
  • g++(他のコンパイラでも動くはず)

依存関係を全て揃えたら、以下の通りに実行することでpeacockをビルドできる:

$ cd cpp
$ mkdir build
$ cd build
$ cmake ../src
$ make

自分の環境ではうまくImageMagickを認識できなかったので、cmakeに以下のようなオプションをつけて実行した:

$ cmake ../src -DImageMagick_Magick++_INCLUDE_DIR:PATH=/usr/include/ImageMagick-7 -DImageMagick_Magick++_LIBRARY:FILEPATH=/usr/lib64/libMagick++-7.Q16HDRI.so

makeまでの手順が終わると手元にpeacockというバイナリが生成されているので、手で適当な場所にインストールした:

$ sudo install peacock /usr/local/bin 

これでインストールは完了した。

Peacockを使う

実際にpeacockを使ってみよう。peacock コマンドに画像ファイルのパスを渡すと、CB_というプレフィックスのついた画像がたくさん生成される。これらの一枚一枚がそれぞれの色覚特性に対応している(うち1枚はNormal、つまり一般人の色覚になっている)

$ peacock IMG20220525102718.jpg
Processing: IMG20220525102718.jpg
Performing conversion to ALL representations of colorblindness...
  Performing conversion to Normal...
    Writing CB_Normal_IMG20220525102718.jpg...
  Performing conversion to Monochromacy...
    Writing CB_Monochromacy_IMG20220525102718.jpg...
  Performing conversion to Protanopia...
    Writing CB_Protanopia_IMG20220525102718.jpg...
  Performing conversion to Deuteranopia...
    Writing CB_Deuteranopia_IMG20220525102718.jpg...
  Performing conversion to Tritanopia...
    Writing CB_Tritanopia_IMG20220525102718.jpg...
  Performing conversion to Protanomaly...
    Writing CB_Protanomaly_IMG20220525102718.jpg...
  Performing conversion to Deuteranomaly...
    Writing CB_Deuteranomaly_IMG20220525102718.jpg...
  Performing conversion to Tritanomaly...
    Writing CB_Tritanomaly_IMG20220525102718.jpg...

ファイル名は、CB_特性名_元画像名の形式で出力される。

ImageMagickで複数の画像をモンタージュする

さて、色覚特性に基いた画像を入手することができたが、このままだと「この色合いはアクセシブルかな〜」といった感じでエンジニアやデザイナが眺める用途には適していないので、これらを1枚のモンタージュに統合する。さいわい、ImageMagickにはmontageというコマンドが用意されており、複数の画像を特定の方法で1枚にモンタージュすることができる。

以下のコマンドを用いて、複数の画像をモンタージュする:

$ montage -label '%f' -frame 10 -tile 4x2 -geometry x400 CB_*.jpg  montage.jpg

各オプションの説明は以下の通り:

  • -label '%f' ファイル名をフレームにラベルとして記載する。
  • -frame 10 画像に対して幅10pxのフレームを追加する。
  • -tile 4x2 4列2行のモンタージュを行う。
  • -geometry x400 画像1枚あたり縦400pxとする(2行あるので800pxになり、フレーム分でやや増えて最終的に872pxになる)。

これにより、冒頭のような画像が得られる。

シェルスクリプト化する

Peacockによる画像生成とモンタージュ化を手動でやるのは大変なので、画像を渡すだけでモンタージュまでやってくれるシェルスクリプトを作成した。

#!/bin/bash

# Generates color blindness comparison montage from $1.
# Outputs `CBM_$1` to current directory (if exists, overwritten without warning).

set -ex

FILE=${1?Please specify file name as first argument.}

ABS_FILE=$(realpath "$FILE")
ABS_PATH=$(dirname "$ABS_FILE")
FILENAME=$(basename "$FILE")
EXT="${FILENAME##*.}"

TMPDIR=$(mktemp -d)
cd "$TMPDIR" || exit 1
cp "$ABS_FILE" "$FILENAME"
peacock "$FILENAME"
montage -label '%f' -frame 10 -tile 4x2 -geometry x400 CB_* "cbm.$EXT"
mv "cbm.$EXT" "$ABS_PATH/CBM_${FILENAME}"
rm -rf "$TMPDIR"

これを実行すると、全自動でCBM_渡した画像ファイルというファイルにモンタージュが生成される。

実際にグラフをモンタージュしてみた

さて、本題に戻って、先日書いた記事のグラフがアクセシブルかどうか確認してみる。

blog.3qe.us

windymelt% ./generate-color-blindness-montage.sh 20221010115140.png
+ FILE=20221010115140.png
++ realpath 20221010115140.png
+ ABS_FILE=/home/windymelt/Downloads/20221010115140.png
++ dirname /home/windymelt/Downloads/20221010115140.png
+ ABS_PATH=/home/windymelt/Downloads
++ basename 20221010115140.png
+ FILENAME=20221010115140.png
+ EXT=png
++ mktemp -d
+ TMPDIR=/tmp/tmp.QTijEfrp4K
+ cd /tmp/tmp.QTijEfrp4K
+ cp /home/windymelt/Downloads/20221010115140.png 20221010115140.png
+ peacock 20221010115140.png
Processing: 20221010115140.png
Performing conversion to ALL representations of colorblindness...
  Performing conversion to Normal...
    Writing CB_Normal_20221010115140.png...
  Performing conversion to Monochromacy...
    Writing CB_Monochromacy_20221010115140.png...
  Performing conversion to Protanopia...
    Writing CB_Protanopia_20221010115140.png...
  Performing conversion to Deuteranopia...
    Writing CB_Deuteranopia_20221010115140.png...
  Performing conversion to Tritanopia...
    Writing CB_Tritanopia_20221010115140.png...
  Performing conversion to Protanomaly...
    Writing CB_Protanomaly_20221010115140.png...
  Performing conversion to Deuteranomaly...
    Writing CB_Deuteranomaly_20221010115140.png...
  Performing conversion to Tritanomaly...
    Writing CB_Tritanomaly_20221010115140.png...
+ montage -label %f -frame 10 -tile 4x2 -geometry x400 CB_Deuteranomaly_20221010115140.png CB_Deuteranopia_20221010115140.png CB_Monochromacy_20221010115140.png CB_Normal_20221010115140.png CB_Protanomaly_20221010115140.png CB_Protanopia_20221010115140.png CB_Tritanomaly_20221010115140.png CB_Tritanopia_20221010115140.png cbm.png
+ mv cbm.png /home/windymelt/Downloads/CBM_20221010115140.png
+ rm -rf /tmp/tmp.QTijEfrp4K

Seabornから生成されたグラフを色覚特性に基いてモンタージュした画像

グラフは多くの場合で識別可能だったが、完全に白黒の場合はやや見難いと感じた。アクセシブルなグラフを作成するには、模様を併用したほうが良さそうという知見が得られた。模様を生成することで、例えば白黒コピーを行うといった場合にもそのまま使うことができて、一般人にとっても有益なことが多い。そして、文字で識別できる凡例を添付するのはほぼ必須だとわかる。より良くするには、凡例のラベルをグラフの上に直接描写したほうがよいが、Seabornでそれができるかはわからなかった。

まとめ

色覚特性にもとづいた見え方を一望できるスクリプトを作成した。このスクリプトでよりアクセシブルな世界が広がると良いなと願っている。

おまけ

著者のアイコンがモンタージュされた画像

*1:色盲とか色弱と呼ぶことも多い

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?