[応用編] PNG画像の背景が黒くなる場合の回避策

-extent -size -composite -compose +clone -fill -colorize +swap

イメージマジック

もう少し後に書こうと思っていたのですが、結構お悩みの人も多いようなので、先に書いておきます。
(※少し複雑な内容を含むページですので、特に必要ない方は読み飛ばしてください。)
PNGやGIFなど背景が透過した画像を、JPEGなど透過を保持できない画像にImagemagickでフォーマット変換を行った際に、稀に背景が真っ黒くなってしまうことがあります。


例) convert before.png after.jpg

▼実行結果
画像の背景が黒くなってしまう

Photoshopで普通に書き出したPNG画像を使った上記サンプルですが、なぜか黒くなるだけでは飽き足らず変なことになってしまいました。。汗

色々と試しながら原因を推測していくと、Photoshopなどで画像を書き出す際にマットカラーで指定した色が、変換の際の背景色になると思われることがわかりました。

マットカラーを指定

例) convert before.png after.jpg

▼実行結果
画像の背景が白くなりました。

Photoshopで画像を保存する際に、web用に保存を選択し、マットカラーを白に設定して保存した画像で、同様の変換をしてみたところ、背景白のJPEG画像が生成できました。

というわけで、これで解決・・と言いたいところなのですが、不特定多数のユーザーから画像のアップロードを受けるサービス等、画像の作成環境を指定できない場合も多々ありますよね。
マットカラーを画像に情報として保持しているのならば、identifyコマンドで判別すればいいのではと思い、-formatオプションで色々と漁ってみたのですが、マットカラーの情報は見つけられませんでした。

というわけで、スマートな解決方法が見つけられなかったので、こうなりゃ力技だ・・ということで、私が業務の際に行っていた回避策をご紹介したいと思います。

1.画像サイズがわかっている場合

予め画像のサイズがわかっている場合(もしくはindetify等で画像のサイズを事前に取得した場合)、以下の方法で画像の背景が黒くなるのを防止できます。

convert    <変換前の画像名>    -extent  (width) x (height)  <変換後の画像名>

例) convert before.png -extent 150×150 after.jpg

▼実行結果
画像の背景が白くなりました2

-extentは、画像のサイズを変更するオプションなのですが、このオプションを指定するとなぜか背景が白になります。
全ての環境で試したわけではありませんので、バージョンやファイル形式等によりできない場合もあるかもしれません。
そもそも、-background等で事前に背景色を指定していないのに、白くなるのがかなり謎です。。
他にも-frame 0x0とかでも似たような感じになるのですが、真っ白ではなく薄いグレー等になってしまうことがあります。

上記はコマンドが短くて簡単なのですが、イマイチ原理がわからないということで2案目の回避策です。

ちょっと長くなりますが、これが一番確実かもしれません。

convert    ¥(    -size    (width) x (height)    xc:#FFFFFF    ¥)    
<変換前の画像名>    -compose  over  -composite    <変換後の画像名>


例) convert ¥( -size 150×150 xc:#FFFFFF ¥) before.png -compose over -composite after.jpg

▼実行結果
画像の背景が白くなりました3

簡単に説明しますと、画像と同じサイズで白い背景画像を作って、画像の後ろに張り付ける方法です。
¥( ¥) は、計算式の () [括弧]のようなものと考えてください。
¥でエスケープする必要があります。
-compositeは2つの画像を合成するオプションです。その前の-compose overで重ね方を事前に指定しています。

2.画像サイズがわからない場合

最後に、画像のサイズがわからない、もしくは取得するのが面倒な場合には以下のような書き方が可能です。

convert    <変換前の画像名>    ¥(   +clone   -fill  “#FFFFFF”  -colorize 100%  ¥)  
+swap  -compose  over  -composite    <変換後の画像名>


例) convert before.png ¥( +clone -fill “#FFFFFF” -colorize 100% ¥) +swap -compose over -composite after.jpg

▼実行結果
画像の背景が白くなりました3

何をやっているのかを説明しますと、+cloneで元画像の複製画像を生成しています。
さらにそれを-fill “#FFFFFF” -colorize 100%で白く塗りつぶしています。
最後に+swapで画像の重ね順を変えて、-compositeで合成するという流れです。

元画像を複製するため、サイズがわからなくても大丈夫、というわけです。
注意点としては、-fillでカラーを指定する際には、 ” ” でカラーを囲む必要があります。

以上、背景が黒くなってしまう場合の回避策を幾つか紹介いたしました。

本当はもっとスマートな方法をご提示したかったのですが、私の実力不足もありまして、どうもすいません。。汗
何か他に方法をご存知の方は、お教えいただけると嬉しいです。

ではでは。

最後までお読みいただきありがとうございます。お役に立てましたなら嬉しいです