現在、GDI+を利用して読み込んだ画像ファイルをウィンドウ上に描画させたいと考えています。
通常であれば、以下のようにして簡単に描画できるのですが、プログラムの性質上
何度も画像を描画しなおすため、動作が非常に遅くなってしまいます。
char * filename; // 表示させたい画像ファイル
BSTR bstrFileName;
bstrFileName = _bstr_t(filename).copy();
Bitmap bmp = new Bitmap(bstrFileName);
Graphics Grp(hdc);
Grp.DrawImage(bmp, 0, 0, 600, 600);
フォーマットを気にせずロードできる手軽さと、縮小のアンチエイリアシングの良さ(?)から
GDI+を選んだのですが、こう遅いと実用できません。
OleLoadPictureFileを使う手段も考えましたが、StretchBltで転送した際に画像がノイズのように
なってしまいうまくいきませんでした。
(原因不明です…。)
そこで、一度プログラムで利用するサイズに変形した後、DIB形式に変換しキャッシュしてしまい、
以降はキャッシュしたDIBを利用したいと考えました。
いろいろ探して、Bitmap.LockBitsやらBITMAPDATAなどから取得できるのかな…?程度には見つけたのですが
具体的な方法がいまいちわかりません。
どなたかわかる方いましたら、教えてもらえないでしょうか?。。
Code ProjectかCode Guruあたりに、GDI+でのダブルバッファリングのサンプルがあったと思うんですが、ご覧になりました?
漠然とDIBに変換したい…としか考えてなかったので見てませんでした…
ちょっと見てみます〜
いくつかサンプルコードを見つけ、参照してみたのですが、どれも自分のやりたいこととは違っていました。。
現在やりたいことは、Bmp,JPEG,GIFなどの画像を読み込みパズルゲームを作りたいのです。
パズルを移動するごとに何度も再描画しているため、GDI+の処理では遅くなってしまいます。
そこでDIBに変換しBitBltで転送すれば、それなりに速度が向上できるのではないかと考えたのです。
(簡単なパズルゲームなので、体感速度がそれなりであればいいかなと)
Bitmap::LockBits()を利用してBitmapDataよりビットマップのピクセルデータを得られる、ということはわかったのですが、それをどうすればいいのかが…。
DIBについてもわかっていない部分もあるので、手がかりなど教えてもらえないでしょうか。
DIBだとか、GDI+云々というよりは、描画処理の効率が悪いためではないかと思うんですが。
gdiplus::BitmapからDIBを作っても二度手間になるだけのような気がします。(たぶん)
実際の描画部分のコードがわからないんですが、
>Graphics Grp(hdc);
>Grp.DrawImage(bmp, 0, 0, 600, 600);
これだと、毎回全ての領域が描き直されるので、描画する必要がある部分のみを描き直すようにすればどうですか?
InvalidateRectに再描画が必要な最小限の座標を指定して、MFCならOnPaint内にてGetClipBoxでその座標を取得、裏画面に描画して画面に転送、というような感じですが。
それと、
>char * filename; // 表示させたい画像ファイル
>BSTR bstrFileName;
>bstrFileName = _bstr_t(filename).copy();
>Bitmap bmp = new Bitmap(bstrFileName);
これだと、毎回ファイルから読み込んでgdiplus::Bitmapを構築していることになるんですが、毎回ファイルを読むのは時間がかかります。
また、GDI+ではないんですが、
http://wisdom.sakura.ne.jp/system/winapi/win32/win134.html
は参考になりません?
あと、VisualC++に付属のdrawcliというサンプルとか。
はずしてたらごめんなさい。
>これだと、毎回全ての領域が描き直されるので、描画する必要がある部分のみを描き直すようにすればどうですか?
>InvalidateRectに再描画が必要な最小限の座標を指定して、MFCならOnPaint内にてGetClipBoxでその座標を取得、裏画面に描画して画面に転送、というような感じですが。
見逃してました。
これから少し試してみます。
>これだと、毎回ファイルから読み込んでgdiplus::Bitmapを構築していることになるんですが、毎回ファイルを読むのは時間がかかります。
すみません、書き方が悪かったようです;;
ファイルの読み込み部分は開く画像を指定したときのみ実行されているので、1度しかファイルを読み込んでいません。
最初、LoadImageを使ってロードしたビットマップ画像を描画した際には、望むだけの描画速度がでていたのですが、GDI+にて同様の処理を行ったところ処理速度が低下したためGDI+の問題ではないかと思い込んでいました…。
上記のサイトを参考にクリッピングを使ってコーディングしてみます。
ツイート | ![]() |