2017年02月22日

◇Magick.NET 単色PNG画像を保存した際の不可解な挙動

▼解決しました。

 保存時の設定を以下のようにするとうまく行くようです。


MagickImage.Settings.SetDefine( MagickFormat.Png, "color-type", "3" );
MagickImage.Settings.SetDefine( MagickFormat.Png, "bit-depth", "2" );
MagickImage.Settings.ColorType = ColorType.Palette;
MagickImage.Format = MagickFormat.Png8; // ここを MagickFormat.Png → MagickFormat.Png8 に変更した。

 どうやら MagickFormat.Png 指定は「指定された画像に最適化を加えてPNG形式で保存する」というもので、 MagickFormat.Png8は「256色を上限としたパレットカラー」、MagickFormat.Png24は「RGB各8bitのフルカラー」として扱うという事のようです。

▼以下、未解決時点のお話

 Magick.NET 7.0.701を使用して2bitカラーパレットのPNG画像を作成・保存したときに遭遇したおかしな挙動について。

 グレースケールのグラデーション画像を作成し、ディザリングの効果を確かめたんですが、 階調表現が3〜5の時はこのように正常にディザやポスタライズが行われています。



この画像を↓




 見ての通り、左端が白で右に行くに従い黒が濃くなっていくグラデーション画像なんですが、 これを2階調で減色したあと保存するとこうなります。



何も表示されませんね。ブログにアップロードするとなぜか画像が壊れました。

 実際はどういう表示になっていたかというと、こうです。



どういうわけか白黒が反転していて、どのような処置を取っても正常な結果で保存されないです。

 実はこのPNG画像を出力する前にPNGチャンクを分解し、あとで連結という処理を入れており、それが原因となっているのかと思ったんですが、 分解・再結合の処理を入れる前の状態で出力させてもやはり画像がおかしくなっており、どうもMagick.NET(ImageMagick)側のバグではないか……と言う気がしています。

 軽く調査したところ、4bitカラーパレットを持つ画像で2色しか使っていないという条件でも同様に色がおかしくなる現象が出ており、 PNG(多分libpng)の「使わない色は削除し、透明色を優先してパレットを並び替える」という挙動が原因となっているのではないか、と言及されていました。

 一応対策としてImageMagickのコマンドラインオプションから -define png:preserve-colormap を指定すると解決するかもしれないという提案はありましたが、 Magick.NETでこれを試すとパレットを持つ画像で使えという旨の例外が出てしまい、うまくいきません。

 Magick.NETで保存した場合に限り、色数が2色以下の1/2/4/8bit画像は壊れるというのを確認しています。現時点では打つ手がない有様なため、2色以下のPNG画像については封印しておく必要があるかもしれません。

posted by いわとび ぺんぎん at 18:58| 沖縄 ☁| Comment(0) | ◇プログラミング関連 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]