
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も見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
C言語・Windows RECTが渡せない
-
ウインドウサイズを変更しても...
-
VC++プログラムをつかったBMP画...
-
google Colabでmatplotlibの描...
-
ClistBoxでオーナードローがよ...
-
panelのスクロール表示について
-
矢印を描画するには
-
DirectX9.0での四角形の描画に...
-
DirectXで曲面の描画
-
vb.netでテキストボックス内の...
-
CStaticコントロールの静的イメ...
-
DirectXの表示領域
-
Labelの文字をスクロールする際...
-
DirectXとGDIの違い
-
ローディング画面をマルチスレ...
-
楕円を描くプログラミング
-
画像を重ねて動かすと重くなり...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
TextBoxに文字を書いても表示さ...
-
VB6,リストボックスの特定行の...
-
NVIDIAのシェーダーキャッシュ
-
panelのスクロール表示について
-
VC++プログラムをつかったBMP画...
-
VBAにGDI+を参照させる方法
-
google Colabでmatplotlibの描...
-
MFCでOnPaintのタイミング
-
MFCのタイマーのつかい方を教え...
-
UpdateData( FALSE); による文...
-
CStaticコントロールの静的イメ...
-
Form1 Load で実行されない。
-
InvalidateRectの使い方について
-
win32api 画面のちらつき
-
c++ ダブルバッファリング、以...
-
CDC(LineTo)で描画した線を透過...
-
BitBltでの表示での問題です。
おすすめ情報