注意:画像の表示方法が分からないという方は、まず「コントロールやフォームに画像を表示する」をご覧ください。
ここでは、「画像ファイルを読み込み、Imageオブジェクトを作成する」のように画像ファイルを読み込んでImageオブジェクトを作成するのではなく、プログラムで動的に作成する方法を紹介します。この方法を使えば、プログラムで線や図形、画像、文字などを自由に描画してImageオブジェクトを作成して、コントロールに表示したり、ファイルに保存したりすることができます。
Imageオブジェクトを動的に作成する手順は、次のようになります。
補足:Imageクラスは抽象クラスで、Bitmapクラスはその派生クラスです。
早速ですが、具体例を示します。この例では、動的にImageオブジェクトを作成して、黒い背景に黄色の扇形を描画し、その画像をPictureBoxコントロール(PictureBox1)に表示しています。
'Imports System.Drawing '200x100サイズのImageオブジェクトを作成する Dim img As New Bitmap(200, 100) 'ImageオブジェクトのGraphicsオブジェクトを作成する Dim g As Graphics = Graphics.FromImage(img) '全体を黒で塗りつぶす g.FillRectangle(Brushes.Black, g.VisibleClipBounds) '黄色い扇形を描画する g.DrawPie(Pens.Yellow, 60, 10, 80, 80, 30, 300) 'リソースを解放する g.Dispose() '作成した画像を表示する PictureBox1.Image = img
//using System.Drawing; //200x100サイズのImageオブジェクトを作成する Bitmap img = new Bitmap(200, 100); //ImageオブジェクトのGraphicsオブジェクトを作成する Graphics g = Graphics.FromImage(img); //全体を黒で塗りつぶす g.FillRectangle(Brushes.Black, g.VisibleClipBounds); //黄色い扇形を描画する g.DrawPie(Pens.Yellow, 60, 10, 80, 80, 30, 300); //リソースを解放する g.Dispose(); //作成した画像を表示する PictureBox1.Image = img;
上の例ではBitmapのコンストラクタに、作成する画像のサイズだけを指定しています。このようにして作成されたImageオブジェクトは、すべてのピクセルが無色透明([A=0, R=0, G=0, B=0])です。
Graphicsオブジェクトに図形等を描画する方法は、このサイトでは、「長方形、多角形、楕円、円弧、扇形を描く」、「線を描く」、「曲線を描く」、「文字を描く」などで詳しく説明していますので、そちらをご覧ください。
わざわざ説明するほどのことではないかもしれませんが、この方法を使って、すでに存在しているImageオブジェクトに描画することもできます。例えば画像ファイルを「画像ファイルを読み込み、Imageオブジェクトを作成する」の方法でImageオブジェクトにしてから、文字や図形、あるいは他の画像など描画するといったこともできます。
以下の例では、画像ファイル(C:\test\1.bmp)の左上に文字列(DOBON.NET)を描画して、ファイルに保存しています。Imageオブジェクトをファイルに保存する方法は、「画像フォーマットを指定して保存する」をご覧ください。
'Imports System.Drawing '画像ファイルを読み込んでImageオブジェクトを作成する Dim img As New Bitmap("C:\test\1.bmp") 'ImageオブジェクトのGraphicsオブジェクトを作成する Dim g As Graphics = Graphics.FromImage(img) '文字列("DOBON.NET")を左上に描画する Dim fnt As New Font("Arial", 12) g.DrawString("DOBON.NET", fnt, Brushes.Black, 0, 0) fnt.Dispose() '作成した画像を保存する img.Save("C:\test\new1.bmp") 'リソースを解放する g.Dispose() img.Dispose()
//using System.Drawing; //画像ファイルを読み込んでImageオブジェクトを作成する Bitmap img = new Bitmap(@"C:\test\1.bmp"); //ImageオブジェクトのGraphicsオブジェクトを作成する Graphics g = Graphics.FromImage(img); //文字列("DOBON.NET")を左上に描画する Font fnt = new Font("Arial", 12); g.DrawString("DOBON.NET", fnt, Brushes.Black, 0, 0); fnt.Dispose(); //作成した画像を保存する img.Save(@"C:\test\new1.bmp"); //リソースを解放する g.Dispose(); img.Dispose();
実はGraphicsオブジェクトを作成しなくても、Bitmap.SetPixelメソッドを使えば任意の点(ピクセル)の色を変えることが出来ます。
以下の例では、Imageオブジェクトのランダムな位置にランダムな色をつけています。
'Imports System.Drawing '200x100サイズのImageオブジェクトを作成する Dim img As New Bitmap(200, 100) 'ランダムな色の点をランダムな位置にうちまくる Dim rnd As New Random() For i As Integer = 0 To 2000 '色を決める Dim c As Color = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)) '1つのピクセルの色を変える img.SetPixel(rnd.Next(img.Width), rnd.Next(img.Height), c) Next '作成した画像を表示する PictureBox1.Image = img
//using System.Drawing; //200x100サイズのImageオブジェクトを作成する Bitmap img = new Bitmap(200, 100); //ランダムな色の点をランダムな位置にうちまくる Random rnd = new Random(); for (int i = 0; i < 2000; i++) { //色を決める Color c = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)); //1つのピクセルの色を変える img.SetPixel(rnd.Next(img.Width), rnd.Next(img.Height), c); } //作成した画像を表示する PictureBox1.Image = img;
例えば画像すべてのピクセルの色を変えるなどのように、多数のピクセルの色を変える場合は、SetPixelメソッドは効率が良くありません。そのような場合は、Bitmap.LockBitsメソッドを使うとパフォーマンスが向上します。この方法は、「色を反転させた画像(ネガティブイメージ)を表示する」で紹介しています。
この記事の本筋からは少しそれますが、PictureBoxコントロールのImageプロパティを使ってImageオブジェクトを表示している場合の補足をします。
PictureBoxコントロールのImageプロパティに新しいImageオブジェクトを設定した場合は、新しい画像がすぐに表示されます。しかし、ここで紹介している方法でImageプロパティに設定されているImageオブジェクトの内容を描き変えた時は、それがすぐには表示に反映されません。Imageオブジェクトの変更をすぐに反映させるには、Invalidateメソッドを呼び出します。
以下の例では、現在の時刻をPicutureBoxコントロール(PictureBox1)のImageプロパティに描画しています。この例では描き変えた後でPictureBox1のInvalidateメソッドを呼び出していますので正常に現在の時刻が表示されますが、もしこれがないとPictureBox1の表示が変わらないことをお確かめください。
'Imports System.Drawing 'PictureBox.ImageプログラミングにImageオブジェクトを設定する If PictureBox1.Image Is Nothing Then PictureBox1.Image = New Bitmap(100, 50) End If 'ImageオブジェクトのGraphicsオブジェクトを作成する Dim g As Graphics = Graphics.FromImage(PictureBox1.Image) '全体を白で塗りつぶす g.FillRectangle(Brushes.White, g.VisibleClipBounds) '現在の時刻を描画する g.DrawString(DateTime.Now.ToLongTimeString(), _ SystemFonts.DefaultFont, Brushes.Black, 10, 10) 'Graphicsオブジェクトのリソースを解放する g.Dispose() 'Imageプロパティの変更を反映させるために、PictureBox1を再描画する PictureBox1.Invalidate()
//using System.Drawing; //PictureBox.ImageプログラミングにImageオブジェクトを設定する if (PictureBox1.Image == null) { PictureBox1.Image = new Bitmap(100, 50); } //ImageオブジェクトのGraphicsオブジェクトを作成する Graphics g = Graphics.FromImage(PictureBox1.Image); //全体を白で塗りつぶす g.FillRectangle(Brushes.White, g.VisibleClipBounds); //現在の時刻を描画する g.DrawString(DateTime.Now.ToLongTimeString(), SystemFonts.DefaultFont, Brushes.Black, 10, 10); //Graphicsオブジェクトのリソースを解放する g.Dispose(); //Imageプロパティの変更を反映させるために、PictureBox1を再描画する PictureBox1.Invalidate();
なおInvalidateメソッドに関してより詳しくは、「Refresh、Update、Invalidateメソッドの違い」で説明しています。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。