ぴんぐ

フルカラー画像を指定の色パレットに寄せたPNG画像へ変換するプログラムを作っています.パレット番号を指す主の画像データ部分の圧縮に数日,手こずりました.圧縮アルゴリズムは,LZ77とハフマン符号化をコラボレーションしたデフレートなるものが使われているようです.

フリーのzlibなるライブラリを使えば実現できるそうですが,.NET Framework 4.5以降のSystem.IO.Compression.DeflateStreamでもこれが使われているとのこと.余計な外のライブラリとか使いたくないので,.NET一本で行きました.初めて使うのであれこれ調べつつ.

ところが,そうして作ったPNGファイルが,これまで使っていた他のプログラムで開けないとの指摘を受けました.たしかに,貰ったその既成プログラムで開けません.こちらで開けるのは,同じ.NET Frameworkで開こうとするから良い感じに互換するってことでしょうか.エラーメッセージはPNGファイルの形式不正の雰囲気を醸していましたけど,タグ構成とか合っているとしか思えないし,ちゃんとIDATチャンクデータの冒頭にzlibのヘッダっぽい2バイトも足しているというのに,むむむ.

攻め方を変えて今度はDeflateStreamを使わず,単純にSystem.Drawing.BitmapでFormat8bppIndexedなPNGを出力してみました.そもそもこれが一番楽な方法でした.が,これでも貰った既成プログラムで開けません.

仕方ない,zlibを導入するか.しかし,良い感じにDLL化されたものが見つかりません.調べるの下手なのよね.結局,ソースコードをDLしてビルドしてDLLにしました.メソッドの使い方とか呼び方とかいろいろ調べ,何とか実装.が,これでも貰った既成プログラムで開けません.圧縮レベルとかいろいろ変えても駄目.

貰った既成プログラムの更新日,15年近く前になっていました.これはもしや,最新のzlibじゃ駄目ってことかな.ってことで,古のソースコードを掘り出しました.といってもせいぜい10年前のやつ.それ以上は私のGitHub力不足で引き出せませんでした.

さて,その古のソースコード,DLL化するのに一苦労.最新版のはVisual Studioですぐビルドできるようにプロジェクトファイルが付いてきたのですが,10年前のにはありません.そもそも,Linuxを想定されてか,ちょろちょろコンパイルエラーも出ちゃう.地道に潰して,無事DLLにしました.が,これでも貰った既成プログラムで開けません.

libPngを使ってみるか.いや,どの道その中でzlibが使われるしな.もう万策尽きているのでは.そろそろ白旗か.ってところで,コーディングミスに気づきました.

マネージの画像データ配列をアンマネージ配列へコピーせずにzlibのメソッドを呼び出していました.なるほど,メモリ上の不定値群を圧縮して突っ込んだPNGを生成していたのね.そこ直したら無事成功.やったね.今日のてんびん座1位は伊達じゃなかった.なお,.NET Frameworkでの圧縮はうまく行かず終いでした.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です