mattintosh note

どこかのエンジニアモドキの備忘録

ImageMagickでカラーハーフトーン化をやってみる

ImageMagickでカラーハーフトーン化をやってみる

転載対策に「写真をいかに劣化させずに劣化させるか」というわけのわからない目標を思いついたのでやってみました。

ハーフトーン(網点)とは

網点(あみてん)またはハーフトーン(英: Halftone)とは、グレイスケールやカラーの画像を限られた色数(例えば、白い紙上の黒い点など)の小さな点のパターンで表すことで印刷可能にしたものである。印刷は紙の上の各点について、インクを置くか、紙をそのままにしておくかという二値状態で情報を表す。つまり、基本的には二値画像だけが印刷可能である。しかし、網点技法により、連続した色調の画像を再現することが可能で、グレイやカラーの様々な陰影の画像を印刷できる。グレイ階調の網点では基本的に白い背景の上に黒い小さな点のパターンを並べる。十分な距離からこれを見ると、点が非常に小さいため、人間の眼ではその点を識別できず、灰色であるかのように見え、黒い点と白い背景の面積の割合によってその部分の明るさが決まる。例えば、多数の黒い点や大きめの黒い点がある場合、暗い灰色に見え、黒い点が少ない場合や小さめの点だった場合には明るい灰色に見える。 CMYK分離の色網点の例。左から、シアン、マゼンタ、イエロー、ブラック、それらの合成、人間の眼から見てどう見えることを期待しているかを示す。 カラー印刷では、限定された色数のインクを使うことが多い。例えば、よく使われるのは、シアン、マゼンタ、イエロー(黄色)、ブラック(黒)という色のセット(CMYK)である。色網点では、これらの各色のインクについて網点のパターンを生成する。そして、それらパターンを重ね合わせることで、各色の割合に応じた色調が(人間の眼から見て)表現される。 出典: 網点 - Wikipedia

話だけ聞いてもよくわからないと思うので参考画像を。雑誌とかの写真を虫眼鏡とかで見るとこんな感じにたくさんの点が並んでいると思います。

デジタル網点
デジタル網点
Cmglee - 投稿者自身による著作物, CC 表示-継承 3.0, https://commons.wikimedia.org/w/index.php?curid=23700811による

Photoshop には昔からこのハーフトーンを再現する『カラーハーフトーン』というフィルターが用意されています。

Photoshop - カラーハーフトーン
Photoshop - カラーハーフトーン

こちらの元画像に対してカラーハーフトーンフィルターをかけてみます。

元画像
元画像

すべてのチャンネルのアングルを 0 に設定した場合

Photoshop - カラーハーフトーン
Photoshop - カラーハーフトーン

すべてのチャンネルのアングルを 45 に設定した場合

Photoshop - カラーハーフトーン
Photoshop - カラーハーフトーン

チャンネルごとにアングルを変更した場合

Photoshop - カラーハーフトーン
Photoshop - カラーハーフトーン

このようにチャンネルごとのアングルを変更することによって印象が変わります。(イラスト界隈だと 45 度が多いのかな?)

さて、Photoshop のカラーハーフトーンでは明らかに元の写真と差が出てしまっていますし、等倍ではまともに見ることもできません。もう少し元の写真のディティールを残したままにしておきたいところです。

ところで ImageMagick にはこのようなハーフトーン化する機能はあるのだろうか?と思って調べてみたところ Digital Halftone Dithers の項目があり、-ordered-dither というオプションがあるようです。

imagemagick.org

-ordered-dither h4x4a で 45 度でかけてみます。

convert -ordered-dither h4x4a
convert -ordered-dither h4x4a

-ordered-dither h4x4a で(多分)0 度でかけてみます。

convert -ordered-dither h4x4o
convert -ordered-dither h4x4o

なんというか…GIF っぽいですね。期待していたのとはちょっと違う感じです。

更に読み進めて見ると "Offset HalfTone Dither" という項目があり先程の参考画像が掲示されていました。

imagemagick.org

例として 2 種類のコマンドが並んでいますが最初これを読んでも理解できませんでした。

magick colorwheel.png  -set option:distort:viewport '%wx%h+0+0' \
          -colorspace CMYK -separate null: \
          \( -size 2x2 xc: \( +clone -negate \) \
                +append \( +clone -negate \) -append \) \
          -virtual-pixel tile -filter gaussian \
          \( +clone -distort SRT 60 \) +swap \
          \( +clone -distort SRT 30 \) +swap \
          \( +clone -distort SRT 45 \) +swap \
          \( +clone -distort SRT 0 \)  +swap +delete \
          -compose Overlay -layers composite \
          -set colorspace CMYK -combine -colorspace RGB \
          offset_colorwheel.png
magick parrots_med.png  -set option:distort:viewport '%wx%h+0+0' \
          -colorspace CMYK -separate null: \
          \( -size 2x2 xc: \( +clone -negate \) \
                +append \( +clone -negate \) -append \) \
          -virtual-pixel tile -filter gaussian \
          \( +clone -distort SRT 2,60 \) +swap \
          \( +clone -distort SRT 2,30 \) +swap \
          \( +clone -distort SRT 2,45 \) +swap \
          \( +clone -distort SRT 2,0  -blur 0x0.7 \) +swap +delete \
          -compose Overlay -layers composite \
          -set colorspace CMYK -combine -colorspace RGB \
          offset_parrots.png

実際に 2 つのコマンドを実行してみてどうなるか確認してみましょう。

-distort SRT
-distort SRT

-distort SRT
-distort SRT

これまでのハーフトーン化と比較するとどちらも「見れる」レベルです。

さて、先程のコマンドは何をしているのかざっくり見てみると、

  1. CMYK に分離する
  2. 白・黒のチェッカー柄の 2x2 ピクセルを C・M・Y・K の各レイヤーに角度を変えて重ねる(足りない分は -virtual-pixel tile によって補われている)
  3. オーバーレイでレイヤーを合成
  4. CMYK から RGB に変換

ということをしているようです。点の拡大用なのか -filter gaussian も入っています。

これを上手く調整すれば見た目をそこまで落とさずにハーフトーン化できそうです。

んで出来たのがこれ。

ImageMagick オリジナルハーフトーン化
ImageMagick オリジナルハーフトーン

convert "${f}" \
        -profile /usr/local/Cellar/ghostscript/*/share/ghostscript/*/iccprofiles/srgb.icc \
        -intent Relative \
        -filter Lanczos2 -distort Resize 5120x5120 \
        -set option:distort:viewport '%wx%h+0+0' -colorspace CMYK -separate null: \
        \( -size 2x2 xc: \( +clone -negate \) +append \( +clone -negate \) -append \) -virtual-pixel tile -filter Spline \
        \( +clone -distort SRT 3,105 \) +swap \
        \( +clone -distort SRT 3,075 \) +swap \
        \( +clone -distort SRT 3,090 \) +swap \
        \( +clone -distort SRT 3,015 \) +swap \
        +delete -compose Overlay -layers composite -set colorspace CMYK -combine -colorspace RGB \
        -filter Lanczos2 -distort Resize 2560x2560\> \
        -level 0%,100%,2.0 \
        -quality 95 \
        $(date +%Y%m%d%H%M%S)_"${f##*/}".jpg
done

ほとんど ImageMagick 公式のサンプルと同じですが、最初に拡大して後からリサイズすることでドットを小さくするようにしているところと明るさを持ち上げている点が異なります(リサイズは意味あるのかどうかは検証中)。欠点は 5120x5120 で一旦処理するのでちょっと重いところですかね。

下記は比較用に上半分をハーフトーン化、下半分をそのままにしたものです。

ImageMagick オリジナルハーフトーン化
ImageMagick オリジナルハーフトーン

等倍だとこんな感じ。

Twitter にサンプルをあげてみたところサムネイルではほぼ劣化は見られず、拡大してみることでハーフトーン化されていることがわかります。

私は写真を等倍で見るタイプなのですがそうではない人も多いと思います。そういう方は拡大しないので恐らくハーフトーン化されていることにはほとんど気づかないと思います。人によってはハーフトーン化されていても脳内補完であまり気にならないでしょう(知らんけど)。

以上、「写真をいかに劣化させずに劣化させるか」というお話でした。(自己満)

リサイズしたときに絶対モアレ発生させるマンになろうと思って始めたんだけどな…(´・ω・`)