GDI+を利用してお絵かきツールのようなものを作成しようと思っています。
しかしdrawImage()での画面への描画が非常に遅いようで、描いてみると線がカクカクしてしまいます。
アンチエイリアスやアルファブレンドが必要なのでGDI+を利用したいのですが、どうにか高速に描画させる方法はないでしょうか?
下記は現在のソースの一部です。
static Bitmap *offscreenBitmap//描画処理はこっちに
static Graphics *offscreen;
static Graphics *onscreen;//画面表示用
static RECT rect;//クライアント領域
static POINTS posPts,pts; //一つ前と現在のマウス座標
static BOOL bLButtonDown;
Pen nomalPen(Color(100,0,0,0), 1); //描画用ペン
switch(msg){
case WM_CREATE:
GetClientRect(hWnd,&rect);
offscreenBitmap = new Bitmap(rect.right, rect.bottom);//ビットマップ生成
offscreen = new Graphics(offscreenBitmap);
offscreen->SetCompositingMode(Gdiplus::CompositingModeSourceOver);
offscreen->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);//アンチエイリアス有効化
offscreen->Clear(Color(255,255,255));//初期化
onscreen = new Graphics(hWnd);//ウインドウ表示用
onscreen->SetCompositingMode(CompositingModeSourceCopy);
break;
case WM_LBTTONDOWN:
bLButtonDown = TRUE;
posPts=MAKEPOINTS(lp)
break;
case WM_MOVE:
pts=MAKEPOINTS(lp)
if(bLButtonDown){
offscreen->DrawLine(&nomalPen, posPts.x, posPts.y, pts.x, pts.y);//線描画
posPts.x=pts.x;
posPts.y=pts.y;
}
InvalidateRect(hWnd,&rect,0);//ウインドウを更新
break;
case WM_PAINT:
onscreen->DrawImage(offscreenBitmap,0,0);//画面に書き出し
break;
}
No.3ベストアンサー
- 回答日時:
昔の絵描きツールでは一般に
1.MouseがDown->Move->UpまではキャッシュDC(GetDC())に書き出す。
2.この間描画データ(=1ストローク=座標の配列)は別途保管
3.Mouse Upで、裏DCに1ストロークを描画しなおし。
4.アンドInvalidateRectする(もちろんストロークデータを
含む矩形のみを無効化)。
5.WM_PAINTで「裏->表」転送を実行
てな感じです。最近はPCが早いのでこうなってない場合も多いです。
どこか参考になるところがあれば幸いです。
回答ありがとうございます。
getDC()で得られるDCってことはこの場合Onscreenってことですかね。ちらつきを抑止したいのでこれは試していませんが、無効化の領域を絞ることである程度速度が改善しました。
No.2
- 回答日時:
こんばんは。
offscreen->DrawLine(&nomalPen, posPts.x, posPts.y, pts.x, pts.y);
の代わりに
onscreen->DrawLine(&nomalPen, posPts.x, posPts.y, pts.x, pts.y);
へ直描きした場合が一番高速でした。
バックバッファ(オフスクリーン)への書き込みが相当に重たいようです。
初めてマウスを押したポイントと、離されたポイントの矩形領域を、バックバッファにストアした方が効果的かもしれません(アンドゥ・リドゥ程度ならば此れ出来そう)。
但し、リアルタイムにエフェクターを掛けながら描写をする場合は、どうしても作業用のバックバッファが必要になりそうです。
一応CachedBitmapと言うのが速いらしいのですが、
「参考資料」
http://lamoo.s53.xrea.com/develop/gdiplus/gdiplu …
http://lamoo.s53.xrea.com/develop/gdiplus/gdiplu …
画面に書き出す際に
onscreen->DrawImage(offscreenBitmap,0,0);
とする代わりに、こんな感じで呼び出す
CachedBitmap offcache(offscreenBitmap, onscreen);
onscreen->DrawCachedBitmap(&offcache, 0, 0);
らしいのですが、反ってスピードが落ちました・・・。
後、new Bitmap()の第3パラメータに「PixelFormat32bppRGB」とかを指定しても駄目でしょうか(少~しだけ速くなった気がした)。
回答ありがとうございます。
元々GDIで作っていたのですがアンチエイリアスや回転処理が欲しくなったのでGDI+に切り替えようとしてのっけから躓いてました。
URLの速度比較を見る限りGDI+は圧倒的に遅いみたいですね…
GDI+のメソッド云々よりもGdiplus::Bitmapが重いんですかね。GDI::DDBにGDI+のメソッドが使えればいいのに
No.1
- 回答日時:
GDI+を使ったことはありませんが、下記の(1)か(2)の方法で描画速度を上げられると思います。
(1)
case WM_MOVE:でのInvalidateRectをやめ、代わりにonscreenにもoffscreenと同じ線描画を行う。
(2)
case WM_MOVE:でのInvalidateRectで更新する領域をposPts.x, posPts.y, pts.x, pts.yの範囲にする。
case WM_PAINT:で更新を必要とする領域を取得(PAINTSTRUCT)し、その領域のみを再描画する。
回答ありがとうございます。
描画中のちらつきは避けたかったので1の方法は用いずに2の方法を試したところかなり速度が向上しました。
GDIの描画処理自体も相当鈍重ですが画面の更新も結構リソース食うんですね
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- JavaScript セレクトボックスを2つ選択してメッセージなどを表示するには。~運賃検索プログラムを完成させたい~ 1 2022/07/22 11:10
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
- C言語・C++・C# 【C++】IDirect3DSurfaceのディープコピーは可能ですか? 1 2022/07/06 02:47
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- JavaScript セレクトボックスを2つ設けて選択して初めてメッセを表示 1 2022/07/27 12:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VC++プログラムをつかったBMP画...
-
ワードの図形で重なり部分の色...
-
C# ラバーバンドの描画を快適に...
-
ピクチャとHBITMAP
-
重いグラフィックス処理
-
ウインドウサイズを変更しても...
-
VB.NETでPictureBoxへの描画に...
-
vb.netでテキストボックス内の...
-
C#のタブコントロールについて...
-
MFC ビットマップ描画で残像が残る
-
StretchBlt関数について
-
UpdateData( FALSE); による文...
-
MFCでOnPaintのタイミング
-
VB6,リストボックスの特定行の...
-
当たり判定
-
【VC2008】色反転破線の書き方
-
LineToやMoveToにて描画した線...
-
InvalidateRgn()について
-
SHGetFileInfoでアイコンが取得...
-
C# ゲーム作成 FPSと描画...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
[VB.net] DataGridViewの列ヘッ...
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
TextBoxに文字を書いても表示さ...
-
word
-
UpdateData( FALSE); による文...
-
VC++プログラムをつかったBMP画...
-
InvalidateRectの使い方について
-
StretchBlt関数について
-
OneNote 2010 文字と描画がずれる
-
C# ラバーバンドの描画を快適に...
-
エクセルでガンチャートを作成...
-
C++にて、塗りつぶされた円を描...
-
VBAにGDI+を参照させる方法
-
MFC DrawText 背景色とフォント
-
GDI+で高速な描画
-
MFCのタイマーのつかい方を教え...
-
Labelの文字をスクロールする際...
-
FlexGridの一部のみ表示を更新...
おすすめ情報