Home>C# Tips>

ダブルバッファを使った描画

更新日:2003/08/24

描画を高速化させる常套手段としてダブルバッファがあります。直接画面に描画せずに裏方で用意したバッファに対して描画処理を行い、画面への再描画などはバッファを表示するだけにします。

などのメリットがあります。デメリットはメモリ食いですね。@IT会議室への投稿の使い回し。

クラス構成

MyForm
描画を行うフォーム。ダブルクリックで描画処理が切り替わります。青文字が通常描画、赤い文字がダブルバッファです。

dblbuf.cs

using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;

public class MyForm : System.Windows.Forms.Form {
  private System.ComponentModel.Container components = null;

  private bool mode = false;
  private Bitmap bmp;

  public MyForm() {
    InitializeComponent();
    Rectangle r = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
    bmp = new Bitmap(r.Width, r.Height);
  }

  protected override void Dispose( bool disposing ) {
    if( disposing ) {
      if (components != null) {
        components.Dispose();
      }
    }
    base.Dispose( disposing );
  }

  protected override void OnPaint(PaintEventArgs e) {
    Cursor = Cursors.WaitCursor;
    Graphics g = e.Graphics;
    if (mode) {
      // ダブルバッファモードの場合はビットマップを描画するだけ
      g.DrawImage(bmp, 0, 0);
    }
    else {
      // 通常は毎回描画する
      DrawTest(g, Brushes.Blue);
    }    
    Cursor = Cursors.Arrow;
    base.OnPaint (e);
  }

  // 描画関数
  private void DrawTest(Graphics g, Brush b) {
    string s = "あいうえお";
    float w = g.MeasureString(s, Font).Width;
    for (int i = 0; i < 1000; ++i) 
      for (int j = 0; j < 20; ++j)
        g.DrawString(s, Font, b, w * j, i * Font.Height);
  }

  // バッファへの描画を行う
  private void SetupBitmap() {
    Graphics g = Graphics.FromImage(bmp);
    DrawTest(g, Brushes.Red);
    g.Dispose();
  }

  // ダブルクリックでモード変更
  private void Form1_DoubleClick(object sender, System.EventArgs e) {
    mode = !mode;
    if (mode) {
      Cursor = Cursors.WaitCursor;
      SetupBitmap();
      Cursor = Cursors.Arrow;
    }
    this.Invalidate();
  }

  private void InitializeComponent() {
    this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
    this.ClientSize = new System.Drawing.Size(292, 266);
    this.Name = "Form1";
    this.Text = "Form1";
    this.DoubleClick += new System.EventHandler(this.Form1_DoubleClick);

  }

  [STAThread]
  static void Main() {
    Application.Run(new MyForm());
  }
}

Home>C# Tips>