中井技術工房
VC++6 による BMP/PNG DF変換プロジェクト
変換プロジェクトのプログラムソースの説明
March.08.2011
トップ >
PNG画像変換トップ >
ここ
■
プログラムソースの説明
●
骨子
「PNG 利用術」で紹介されているソフトから少しいじっただけでインストールしています。
PngTestDlg.cpp/h だけ見れば十分です。
●
全体的に悩んだところ
[ コーディングスタイル ]
昔風の C スタイルで書かれていましたので、I/F の関係で呼び出すところも C 風コーディングが必要でした。
[ 2次元配列 ]
画像格納用の2次元配列( **image ) にも悩みました。
わかりやすくするために **ppimage という変数に変えました。
ポインタのポインタです。可変長の2次元配列を取り扱うためのものです。
画像を横1列ごとにスライスして、画像幅*3ドットの配列を確保してRGB データを格納したものが、画像高さ分あります。
その配列の先頭アドレスを表形式に格納したものがアドレス表で、その先頭アドレスが ppimage です。
●
BMP 変換で悩んだところ
1) 4ビットタイプ PNG
下図はネットで株をやっている人達には有名な「リアルタイム世界の株価と為替」からサンプリングした画像です。
4ビットで、カラーパレット付きです。当然4ビットタイプのBMP に変換しました。
4ビットのPNG も4ビットの BMP も、「へえ〜、こんなの使うんだ」と驚きましたが、対応しました。
2) カラーパレット
コンバータ Png2Bmp.exe でイラストのような色数の少ない PNG ファイルをBMP 変換すると4、8ビットタイプのBMP ファイルに変換されます。
4、8ビットタイプはカラーパレットを持っていますのでこの変換が必要です。
そこで同様にカラーパレット付の BMP DF に変換するようにしました。
24ビットタイプにするとぐっと大きなファイルになりますので、色数が少ないと有効です。
3) γ補正
元プログラムでは、γ補正するところがあります。この変換を受けたRGB 情報を別画像ファイルに書き出すと、当然元画像ファイルとは内容が変わってしまいます。
ソースの該当部分( read_png_image( ) )にコメントをつけていますので、プログラム開発時に注意ください。
3) α補正
元プログラムにはありませんでしたが、透過画像(α)対策をしています。
カラータイプ3で、カラーパレットデータの後に tRNS データが定義されているときは、背景を白として補正するようにしました。
また、カラータイプ6では、RGB の後ろについている A バイトで同じように補正しています。
不要なときは、この部分をカットしてください。
●
PNG 変換で悩んだところ
1) カラーパレット
8ビットタイプのBMP DF のときは、カラーパレット付きのPNG DF に変換しています。
2) γ補正
元プログラムの中で、γ=1.0 をセットしていて、そのままにしていますが、若干の違和感があります。
とりあえず、この行をコメントにしています。
3) 4,8ビットタイプ対策
4、8ビットタイプのBMP DF のときは、それぞれ、4,8ビットタイプのPNG DF に変換しています。
●
関数の説明
PngTest.cpp に組み込んだ関数の説明をします。詳しくは PngTest.cpp のソースを参照ください。
できるだけコメントを書き込むようにしましたのでわかりやすくなったとは思いますが?
[ PNG 利用術からほとんどそのまま借用した関数 ]
PngTest.cpp の先頭部分にあります。リターンを void から BOOL に変えた程度です。
理解したコメントを追加してあります。
- BOOL check_if_png( );
- BOOL read_png_info( );
- BOOL read_png_image( );
- BOOL write_png( );
[ 作った関数 ]
今回用意した画像変換用の主な関数です。
理解したコメントを追加してあります。
- void OnPngToBmp( ); -- ボタンクリック時の呼び出し関数
- void OnBmpToPng( ); -- 同上
- void OnClipToPngDF( ); -- 同上
- void OnClipToBmpDF( ); -- 同上
- BOOL BmpDFWrByRGBBuf( ); -- パレットなしの PNG データの BMP DF 書込み
- BOOL BmpDFWrByRGBBufWithPlt8( ); -- 8 ビットタイプパレット付きの PNG データの BMP DF 書込み
- BOOL BmpDFWrByRGBBufWithPlt4( ); -- 4 ビットタイプパレット付きの PNG データの BMP DF 書込み
- BOOL ClipPicGet() -- クリップ画像の取り込み
- BOOL BmpDFWrByClipRGBBuf( ); -- クリップ画像のカラーマップなし、24ビットタイプ BMP DF 書込み
- BOOL BmpDFWrByClipRGBBufWithPlt8( ); -- クリップ画像の8ビットタイプカラーマップ付き BMP DF 書込み
- BOOL BmpDFWrByClipRGBBufWithPlt4( ); -- クリップ画像の4ビットタイプカラーマップ付き BMP DF 書込み
- BOOL PngDFWrByClipRGBBuf( ); -- クリップ画像のパレットなしの8ビットタイプ PNG DF 書込み
- BOOL PngDFWrByClipRGBBufWithPlt8( ); -- クリップ画像のパレット付き8ビットタイプ PNG DF 書込み
- BOOL PngDFWrByClipRGBBufWithPlt4( ); -- クリップ画像のパレット付き4ビットタイプ PNG DF 書込み
- void RGBtableSort(); -- R,G,B を合成した int データを小さい順にソート
●
クリップ画像の取り込み処理
ソースがわかりにくいかもしれませんので、若干の説明を加えておきます。
[ クリップ画像が必要 ]
当たり前ですが、実行時には事前にクリップボードへ画像を取り込んでください。
PrintSceenキー(もしくは Alt+PrintSceen キー)にて。
[ 取り込みは DIB タイプ ]
CF_DIB を指定して取り込んでいます。
これは、BMP DF の先頭部分だけがないイメージで取り出せますので、ヘッダだけつけて書き込めばすぐに BMP DF ができますが、このままでは巨大なファイルになりますので「料理」し、コンパクトにします。
[ 色数判定 ]
BMP も PNG も16色、256色以内ならカラーマップ/BMP もしくはパレット/PNG 付きファイルにすることによりぐっと圧縮できます。
そこで、取り込んだ画像から RGB を取り出し、さらに RGBコード(int)として合成し、色数を判断しています。
色数によって次のように処理しています。
- 16色以内なら、4ビットタイプパレット付きPNG もしくは4ビットタイプカラーマップ付き BMP として保存
- 256色以内なら、8ビットタイプパレット付きPNG もしくは8ビットタイプカラーマップ付き BMP として保存
- 257色以上なら、8ビットタイプパレットなしPNG もしくは、24ビットタイプ BMP として保存
●
α補正
αチャンネルの取扱い
の頁を参照ください。
PNG→ BMP DF 変換には、入手できた画像で検証した変換機能を織り込みました。
詳しくはソースを参照ください。
トップ >
PNG画像変換トップ >
頁トップ