C#に限らず.NETのプログラムでは絵や線などを描画するにはGraphicsオブジェクトに対して描画を行いますが、Graphicsオブジェクトの作成方法で描画速度や挙動が異なります。
Graphicsオブジェクトを取得するメソッドにはCreateGraphics、FromHwnd、FromImageと、コントロールのPaintイベントのPaintEventArgsクラスのGraphicsプロパティから取得する方法があります。
まずは、結果から。
評価は画像を描画する速度と、線を描画する速度とで比較しました。
【描画速度の比較】
こちらはフォームのクライアント領域のサイズ、および描画するGraphicsオブジェクトを変えながら、サイズ1024×1024の画像を2枚、交互に表示した場合の結果です。
(評価プログラムのイメージ)
(描画速度)
上記結果はフレームレートなので、値が大きいほど描画速度が速くなります。
これを見ると、CreateGraphicsを使った場合は、描画する領域が小さい場合は速くなりますが、DoubleBufferedの時が比較的速い結果となりました。
DoubleBufferedとはフォームのDoubleBufferedプロパティをtrueに設定し、PaintイベントのPaintEventArgsクラスから取得したGraphicsプロパティに描画した場合です。
FromImageはフォームのクライアント領域と同じBitmapオブジェクトを作成して、そのBitmapをフォームのBackgroundImageに指定し、このBitmapからFromImageメソッドでGraphicsオブジェクトを取得した場合です。
【線の描画速度の比較】
こちらも同様にフォームのクライアント領域のサイズ、および描画するGraphicsオブジェクトを変えながら、フォームのクライアント領域に1画素おきの縦、横の線を描画した時の結果です。
(評価プログラムのイメージ)
(描画速度)
上記結果は描画が完了するまでの時間なので、値が小さいほど描画速度が速くなります。
こちらもDubleBufferedが圧倒的に速い結果となりました。
【考察】
結果からするとフォームのDoubleBufferedプロパティをtrueにしてPaintイベントのPaintEventArgsクラスから取得したGraphicsプロパティに描画するのがベストのようです。
ただし、Paintイベント内で描画してもBackgroundImageがnullでない場合は、描画速度が遅くなるので注意して下さい。
ちなみに、今回はフォームに描画しましたが、PictureBoxではDoubleBufferedプロパティがありません。
しかし、PictureBoxでも試してみた限り、PictureBoxではDoubleBufferedプロパティがtrueの時と同じ動作をしてくれるようです。
画像を描画する場合、DrawImageメソッドで描画したあとにフォームのRefreshメソッドが必要なFromImageを使った描画が遅くなりました。
線を描画する場合は、線を一本一本描画する様子が見えるか?見えないか?で差が出ています。
FromaImageとDoubleBufferedの場合は一旦、メモリに描画してからフォーム上に表示されるので、高速な結果となりました。
逆にCreateGraphicsなどを使った線の描画はちょっと遅すぎ...
ただ、Paintイベントで画像や線を描画するのは、ちょっと面倒くさいかと思います。
そんな時に、ダブルバッファを手動で行う手法を別途まとめました。↓
ピンバック: 【C#】手動ダブルバッファによる高速描画 | イメージングソリューション