
趣味でC#を使ってWindows Forms Applicationでツールを制作している者です。
Windows10環境でVisual Studio2019を使用しています。
今制作しているツールでは、デスクトップをキャプチャしてForm上のPictureBoxに表示し、マウスドラッグで選択範囲(ラバーバンド)を描画してトリミングする機能を実装しました。
しかしPictureBoxに表示した画像サイズが大きいと描画処理が非常に重くなりカクカクになります。
これは、Graphicsオブジェクトに背景画像を描画してラバーバンドのためにラインを4回描画して合成してPictureBoxに表示する‥ということを毎フレームCPUで行っているからでしょうか?
試しに、最初にGraphicsオブジェクトに背景画像を描画する部分を省くと非常に快適になりますが、引いたラインが残って多重に重なっていってしまうため、やはり毎フレームラインを引く前の状態に戻す必要はあると思っています。
その場合なるべく易しい(本職がプログラマでも無い私でも対処可能な)解決法は無いでしょうか?
GeForce GTX970が入ったマシンで使う想定なので、OpenCLでGPUに処理させれば良いのでしょうか。
ツール制作スキルとしてはよくある実装をDobon.Netにお世話になりながら実装ができる程度のレベルですが、何かライブラリを入れて関数を利用すれば良いくらいなら何とかできそうには思います。
よろしくお願いします。m(_ _)m

No.1ベストアンサー
- 回答日時:
深く考えていません(単なる思い付きです)
一から描画するのではなく、一度PictureBoxの範囲を保存しておいて、それを上書きとかできないんでしょうか?
速いかどうか私にはわかりませんが。
それともラバーバンドを引く前にその部分の背景を保存して置き、ラバーバンドが移動すれば、保存しておいた背景部分(ラバーバンドのあった部分だけのデータ)を上書きするとか。
kihonkanaさんご回答ありがとうございます!
それぞれのご提案、とても参考になりました。
>一から描画するのではなく、一度PictureBoxの範囲を保存しておいて、それを上書きとかできないんでしょうか?
>速いかどうか私にはわかりませんが。
こちらPictureBoxを2枚重ねてフォームに配置しておいて、背景画像用とラバーバンド描画用に分けてマウスドラッグ中はラバーバンドの描画のみ行うようにしたら、1920*1080の画像でもかなり軽くなりました!
>それともラバーバンドを引く前にその部分の背景を保存して置き、ラバーバンドが移動すれば、保存しておいた背景部分(ラバーバンドのあった部分だけのデータ)を上書きするとか。
大きな範囲でラバーバンドを作成した際には効果が薄いかな?と最初は思ったのですが、ラバーバンドの上下左右のライン4つの矩形部分のみ描画して合成する形にすることでかなり処理速度が上がりそうに思いました‥!
現状で厳しくなった場合にぜひ試してみたいと思います。
No.2
- 回答日時:
Windows Formなのが原因かと思います。
Windows Formは元々Delphiに由来しWindows 98等まだまだグラフィックボードと言えばただビットマップに変換しているだけの時代のライブラリです。
ところが現在のWindowsは殆どの画面表示をDirect X経由でGPUが行う構成になっています。
そのためラバーバンドしようとするとGPUがウィンドウをレンダリング→CPUへもってきて加工→GPUが再度ウィンドウをレンダリングという流れになります。
加えてWindows FormはレンダリングのGPU化が不完全でGPUが再度ウィンドウをレンダリングする時にCPU側からかなりの支援を行っています。
解決策としてはWPFを使うというのが手軽だと思います。
WPFはDirect Xにウィンドウやフォントのサイズなどパラメータだけ送ってレンダリングもアンチエイリアシングも全てGPUにお任せです。
加えてラバーバンドもGPUがレンダリングした結果から切り出してそのまま表示先にGPU上ではめ込み合成されます。
izayoimizukiさんご回答ありがとうございます!
なるほど‥とても分かりやすい解説で納得しました。
確かに色々とツールを作るにつれ、限界を感じる場面が増えてきました。
GPUを活かしてくれないのもそうですし、標準のコントロールで可能なカスタマイズの範囲も狭く、特にUIの見た目のプロパティが少なすぎて‥
書籍やネットの情報の少なさからWPFに手を出すかどうかずっと悩んでいたのですが、これを機に勉強を始めてみたいと思います‥!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CAD・DTP 「機能ブロック図」の描画用フリーソフトを教えてください 1 2022/09/23 16:12
- デザイン タブレットパソコンについて。 3 2022/10/22 15:19
- 画像編集・動画編集・音楽編集 daVinciResolveの再生プレビュー画面がカクつきます。 daVinciResolve18を 2 2023/01/20 01:35
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- C言語・C++・C# 【C++】IDirect3DSurfaceのディープコピーは可能ですか? 1 2022/07/06 02:47
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- Windows 10 パソコンの起動時、画面が黒いままのトラブルにつきまして。 4 2022/10/02 18:02
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- モニター・ディスプレイ NVIDIA Geforce GT 710の解像度設定について教えて下さい 3 2022/06/19 13:00
- その他(プログラミング・Web制作) Microsoft Forms とか、それに似たツールで計算をすることはできないか? 2 2023/01/14 11:26
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
panelのスクロール表示について
-
BitBltでの表示での問題です。
-
Minecraft 統合版(PC)の描画距...
-
NVIDIAのシェーダーキャッシュ
-
[VB.net] DataGridViewの列ヘッ...
-
pset関数について
-
ワードの図形で重なり部分の色...
-
Windowのちらつき防止
-
TextBoxに文字を書いても表示さ...
-
CDC(LineTo)で描画した線を透過...
-
描画を透明にする方法
-
GetGlyphOutline() ご利用経験...
-
Form1 Load で実行されない。
-
ワイプ表示について。
-
エクセルでガンチャートを作成...
-
VC++プログラムをつかったBMP画...
-
CDCオブジェクトの作成について
-
VBAにGDI+を参照させる方法
-
MFCタブコントロールのグラデー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
word
-
TextBoxに文字を書いても表示さ...
-
VB6,リストボックスの特定行の...
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
panelのスクロール表示について
-
VC++プログラムをつかったBMP画...
-
Labelの文字をスクロールする際...
-
UpdateData( FALSE); による文...
-
VBAにGDI+を参照させる方法
-
CStaticコントロールの静的イメ...
-
FlexGridの一部のみ表示を更新...
-
Form1 Load で実行されない。
-
VB.netでのライン描画方法がわ...
-
重いグラフィックス処理
-
InvalidateRectの使い方について
-
SHGetFileInfoでアイコンが取得...
-
OneNote 2010 文字と描画がずれる
おすすめ情報