.Net(VB、C#)でのPictureBoxの消える描画/画像について
任意のタイミング(例えば、ボタンがクリックされたときなど)でPictureBoxにグラフィックを描画するには、CreateGraphicsメソッドによりGraphicsオブジェクト(System.Drawing名前空間)を取得し、それに対して描画を行えばよい。
この描画方法は、実際にはPictureBoxに限ったものではなく、フォームも含め基本的にすべてのコントロールで可能であり、単にコントロールの表面にグラフィックを上書きしているようなものである。
ただしこのようにして描画した内容は、ウィンドウをリサイズしたとき(ウィンドウをいったん小さくしてから元のサイズに戻した場合など)や、PictureBoxを覆っていた別のウィンドウが移動したときなどに消えてしまう(リサイズやほかのウィンドウなどにより無効になった画面領域はプログラム自身で再描画する必要があるため)。
消えてしまう描画の対策としては、以下の2パターンの方法がある。
Imageプロパティで指定したビットマップに描画
あらかじめPictureBoxと同じサイズのBitmapオブジェクト(System.Drawing名前空間)を作成してPictureBoxのImageプロパティに設定しておき、グラフィックの描画はそのBitmapオブジェクトに対して行う方法。
またこのようにして描画を行っておけば、その画像をファイルに保存したい場合にも、BitmapオブジェクトのSaveメソッドを使用するだけでよい。
ただしBitmapオブジェクトに対して描画したものをすぐにPictureBoxに反映するためには、PictureBoxのRefreshメソッドを呼び出して、PictureBoxを強制的に更新しなければならない(RefreshメソッドはPictureBoxの画像領域を無効にし、Paintイベントを発生させる)。
Paintイベントで描画
Paintイベントが発生したタイミングでグラフィックを描画する方法。
Paintイベントはコントロールの再描画が必要な場合に発生する。
Paintイベント・ハンドラとなるメソッドでは、メソッドの第2パラメータのGraphicsプロパティからGraphicsオブジェクトを取得できるようになっている。
サンプル
以下はサンプル。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load AddHandler PictureBox5.Paint, AddressOf Me.PictureBox5_Paint End Sub Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click '消える描画 Dim g As Graphics = PictureBox1.CreateGraphics() '------------- 以下の部分は同じ ---------------------------- MyDrawing(g) g.Dispose() End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click '消えない描画(Imageプロパティで指定したビットマップに描画) Dim g As Graphics PictureBox2.Image = New Bitmap(PictureBox2.Size.Width, PictureBox2.Size.Height) g = Graphics.FromImage(PictureBox2.Image) '------------- 以下の部分は同じ ---------------------------- MyDrawing(g) g.Dispose() End Sub Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click '消える画像表示 Dim g As Graphics = PictureBox3.CreateGraphics() '------------- 以下の部分は同じ ---------------------------- MyImageDisp(g) g.Dispose() End Sub Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click '消えない画像表示(Imageプロパティで指定したビットマップに描画) Dim g As Graphics PictureBox4.Image = New Bitmap(PictureBox4.Size.Width, PictureBox4.Size.Height) g = Graphics.FromImage(PictureBox4.Image) '------------- 以下の部分は同じ ---------------------------- MyImageDisp(g) g.Dispose() '当然の事ながら下記でも消えない 'PictureBox4.Image = System.Drawing.Image.FromFile(".\sample.bmp") End Sub Private Sub PictureBox5_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) '消えない描画(Paintイベントで描画) Dim g As Graphics = e.Graphics MyDrawing(g) End Sub Private Sub MyDrawing(g As Graphics) Dim f As New Font("MS Pゴシック", 14) g.DrawString("サンプルテキスト", f, Brushes.Red, 25, 100) g.DrawLine(Pens.Black, 25, 125, 160, 125) Dim b = New SolidBrush(Color.FromArgb(100, Color.Aqua)) g.FillRectangle(b, New Rectangle(20, 95, 145, 45)) Dim p As New Pen(Color.FromArgb(255, Color.Blue), 5) g.DrawRectangle(p, New Rectangle(20, 95, 145, 45)) f.Dispose() End Sub Private Sub MyImageDisp(g As Graphics) Dim bmap As Bitmap = New Bitmap(".\sample.bmp") g.DrawImage(bmap, 0, 0) bmap.Dispose() End Sub End Class |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace CSTest002 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { PictureBox5.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBox5_Paint); } private void Button1_Click(object sender, EventArgs e) { //消える描画 Graphics g = PictureBox1.CreateGraphics(); //------------- 以下の部分は同じ ---------------------------- MyDrawing(g); g.Dispose(); } private void Button2_Click(object sender, EventArgs e) { //消えない描画(Imageプロパティで指定したビットマップに描画) Graphics g; PictureBox2.Image = new Bitmap(PictureBox2.Size.Width, PictureBox2.Size.Height); g = Graphics.FromImage(PictureBox2.Image); //------------- 以下の部分は同じ ---------------------------- MyDrawing(g); g.Dispose(); } private void Button3_Click(object sender, EventArgs e) { //消える画像表示 Graphics g = PictureBox3.CreateGraphics(); //------------- 以下の部分は同じ ---------------------------- MyImageDisp(g); g.Dispose(); } private void Button4_Click(object sender, EventArgs e) { //消えない画像表示(Imageプロパティで指定したビットマップに描画) Graphics g; PictureBox4.Image = new Bitmap(PictureBox4.Size.Width, PictureBox4.Size.Height); g = Graphics.FromImage(PictureBox4.Image); //------------- 以下の部分は同じ ---------------------------- MyImageDisp(g); g.Dispose(); //当然の事ながら下記でも消えない //PictureBox4.Image = System.Drawing.Image.FromFile(".\sample.bmp"); } private void PictureBox5_Paint(object sender, PaintEventArgs e) { //消えない描画(Paintイベントで描画) Graphics g = e.Graphics; MyDrawing(g); } private void MyDrawing(Graphics g) { Font f = new Font("MS Pゴシック", 14); g.DrawString("サンプルテキスト", f, Brushes.Red, 25, 100); g.DrawLine(Pens.Black, 25, 125, 160, 125); SolidBrush b = new SolidBrush(Color.FromArgb(100, Color.Aqua)); g.FillRectangle(b, new Rectangle(20, 95, 145, 45)); Pen p = new Pen(Color.FromArgb(255, Color.Blue), 5); g.DrawRectangle(p, new Rectangle(20, 95, 145, 45)); f.Dispose(); } private void MyImageDisp(Graphics g) { Bitmap bmap = new Bitmap(".\\sample.bmp"); g.DrawImage(bmap, 0, 0); bmap.Dispose(); } } } |