2011年4月28日木曜日

ImageMagick PSD続き、PNGをインデックスカラーで透過

  • PSDをレイヤ単位で分割して重ね合わせること(-flatten)することで再構成するような話をこの間書いたが。
  • あれは嘘だ
  • というかそれだけでは元のレイヤの高さなどが反映されてしまうため、出力サイズが想定のものにならない。なので(-flatten)した後に画像サイズに(-crop)をかけてあげる必要がある。
  • 画像の元サイズが480x480で100x100に出力したい場合はこんな感じになった。
  • 当然前の記事を参照して、レイヤごとのオフセットはあわせること。
  • convert -page +0+0 hoge.psd[1] -page +0+0 hoge.psd[2] -page +0+0 hoge.psd[3] -flatten -crop 480x480+0+0 -geometry 100x100 +repage 100x100 result.gif
  • (追記)レイヤの大きさに影響されないようにするためには-cropの後にさらに+repageして仮想画面のサイズを修正する必要がある
  • これでレイヤのサイズが不均等でも正しく出力されるようになる。
  • -cropしてから-geometryでリサイズする、つまり順番が重要になるわけです。
  • ここからPNGの話。
  • アルファ付きのPNGをリサイズして出力すると。アルファチャネルが崩れる問題がImageMagickにはある。というかなんかいかにもメモリリークしてますよーという感じのゴミが画像にのっかってしまいいかにも見苦しい状態に。
  • というかPNGまわりの実装がImageMagickは非常に怪しく、バージョンによっては何もしなくても、出力時にゴミが入ってしまうようだ。(2011年4月時点で6.6.8に当該バグが存在した、アルファ周りのバグは最新版でも存在)
  • ImageMagickの更新ログを見るとPNGがらみの問題が結構多い。
  • まだまだ未成熟なんだね
  • まあとにかくそんな感じでアルファ付き(透過)、PNGを正しく出力するにはどうすればいいか。いろいろオプションがあるので試してみたがこれといった解は見つからなかった。明らかにバグ。
  • 単なる一色抜きの透過PNGが欲しいだけなのに、8bit Alpha付きのPNGでImageMagickは処理しているのだ。
  • いちばん簡単な解決法。
  • GIFで一旦出力して、(-transparent #XXXXXX)を指定しPNGに変換する。
  • こうすることでImageMagickにおけるPNGのアルファチャネル由来のバグは回避できた。
  • こういう情報をバッドノウハウといいます。