▽pngファイルの操作

libpngを利用してpng形式のファイルを直接操作するクラスを作ってみました。ついでに(?)画像の表示・確認に便利ないくつかのクラスを実装しています。

最新のskLibはこちら。

skLib ver 1.0 [024]
sklib-024.lzh

サンプルプログラムはskLibを使用しています。ソースコードをコンパイルする際はあらかじめ、skLibの環境を整えておいてください。

○画面スクロールのサンプル

サンプルプログラムはこちら。

画面スクロール
sk03a-05.lzh

1600x1600ピクセルのビットマップを表示してるだけです。

画面スクロール
画面スクロールの図

スクロールに関しては、基本的に、MFCに用意されているCScrollViewクラスを使用しています。CScrollViewを自作のskScrollViewクラスでラップしてますが、これは、関数を1個追加しているだけですから・・・ これって、MFCのサンプル?(笑)

どっちかというと、ビットマップを管理するために使っているskBitmapDCクラスの方がおもしろいかもしれません。

ちなみに、このクラスはさらに機能を追加する予定・・・ まぁ、いつになるかわかりませんが。

○拡大・縮小のサンプル

サンプルプログラムはこちら。

拡大・縮小
sk03b-04.lzh

画面スクロールのサンプルに拡大縮小機能を追加しました。

拡大縮小のサンプル
拡大縮小のサンプルの図

ツールバーの『↑』で拡大、『↓』で縮小です。『F』を押すと、画面のサイズにあわせてビットマップを表示します。

画像の上で左クリックするとその位置を中心に拡大します。シフトを押しながら左クリックすると縮小になります。ドラッグして範囲を選択すると、その範囲を画面にあわせて表示します。

いわゆる画像表示系のソフトにありがちな機能をそれなりに実現していますが、そのほとんどはskZoomViewクラスにまとめてあります。skZoomViewクラスを基底にしてビューを作成するだけで、これぐらいは簡単に実現できるという事で。

skZoomViewクラスを使うときは論理座標とデバイス座標が混在する事になりますが、今回のサンプルのように、ダブルバッファ状態にしてしまえば、表示に関してはすべてデバイス座標で簡単になります。

それでも、マウス操作は論理座標とデバイス座標の変換が必要になりますが・・・ まぁ、そのあたりはサンプルを参考にがんばってください。

拡大・縮小はWindowsが持っているSetWindowExt()系の関数とSetViewportExt()系の関数で実現しています。ちなみに、スクロールはSetViewportOrg()で。

簡単に説明すると、元の画像のサイズをSetWindowExt()に、拡大・縮小したあとの後のサイズをSetViewportExt()に指定する事で、実際に表示される画像を変形させています。って、この説明であってたっけ?(´∀`;)

座標空間や座標変換は追求するとおもしろいんですけど難しい分野です。まじめに勉強したい人はペゾルトの『プログラミング Windows95』あたりを穴があくまで読むのが良いかと。って、この本のレビューはまだ書いてなかったっけ。

今回の拡大縮小機能の実装にあたっては『Inside Windows』に載っていた“MFC用の自動スケーリング”を参考にしています。

○png入出力のサンプル

サンプルプログラムはこちら。

png入出力
sk03c-07.lzh

これまでのサンプルにpng入出力機能を追加しました。

png入出力のサンプル
png入出力のサンプルの図

今回のメインであるサンプルですが・・・ あまり、解説する事はありません(笑)

プログラムとしてはskPngIOクラスを利用してpngファイルを読み書きしているだけです。

当然のようにskPngIOクラスもストリーム入出力に対応しています。工夫すれば、いろいろとおもしろい使い方ができるかと。自作プログラムのセーブデータにpng形式で画像を埋め込む・・・ なんて、簡単にできてしまいます。

もうちょっと、MFCのストリーム周りの処理がスマートなら、もっとおもしろい事もできそうなんですが・・・ まぁ、最悪、CMemFileをバッファにすれば凝った事も可能という事で。

○注意点

skPngIOクラスはそれなりに注意深くプログラミングしてありますが、それでも、 エラーを吐いて落ちる事があります。たぶん。

落ちる原因と直接の関係はないんですけど、libpngのエラー処理がsetjmpとlongjmpっていうのがどうもねぇ。いつか、ものすごく暇になったらC++でlibpng全体を書き直してみたいですな。

skPngIOクラスは32ビット(=α情報付き)のデータ入出力にも対応しています。ただし、Windowsのビットマップは24ビット分までしか面倒を見てくれませんから、残りの8ビットはプログラマーが創意工夫してわかりやすく表示する事になります。

今回のプログラムではすっぱりあきらめてますが(笑)


[skLib] Presented by See.Ku [2005/2/3]