DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

画像ファイルを読み込み、Imageオブジェクトを作成する

.NET Framework Windowsフォームアプリケーションでは、画像を表現するクラスとしてImageクラスが用意されています。このサイトで紹介している様々なTipsでも、画像を表示するためにImageオブジェクトを作成しています。ここでは、画像ファイルを読み込んで、Imageオブジェクトを作成する方法を紹介します。

Image.FromFileメソッドで読み込む

Imageクラス(System.Drawing名前空間)のFromFileメソッドを使うと、画像ファイルからImageオブジェクトを作成できます。読み込むことのできる(GDI+でサポートされる)画像ファイルの形式は、MSDNの「イメージ、ビットマップ、およびメタファイル」によると、ビットマップ形式のBMP、JPG、GIF、PNG、EXIG、TIFF、メタファイル形式のWMF(Windows メタファイル)、EMF(拡張メタファイル)、EMF+です。MSDNにはありませんが、これ以外に、アイコンファイル(ICO)を読み込むこともできます。

画像ファイル(C:\test.jpg)をImage.FromFileメソッドで読み込んでImageオブジェクトを作成し、ピクチャボックス(PictureBox1)に表示する例を示します。

VB.NET
コードを隠すコードを選択
'画像ファイルを読み込んで、Imageオブジェクトを作成する
Dim img As System.Drawing.Image = System.Drawing.Image.FromFile("C:\test.jpg")

'画像を表示する
PictureBox1.Image = img
C#
コードを隠すコードを選択
//画像ファイルを読み込んで、Imageオブジェクトを作成する
System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\test.jpg");

//画像を表示する
PictureBox1.Image = img;

このようにして作成したImageオブジェクトは、使い終わったらDisposeメソッドを呼び出してリソースを解放してください。例えば上記の例では、ImageオブジェクトをPictureBox.Imageプロパティに設定している間はDisposeメソッドで解放せず、完全に使用しなくなってから解放してください。

なおImage.FromFileメソッドは、読み込もうとした画像ファイルがサポート外の場合、例外としてOutOfMemoryExceptionをスローすることに注意してください。

Imageクラスは抽象クラスで、その派生クラスにはBitmapクラス(System.Drawing名前空間)とMetafileクラス(System.Drawing.Imaging名前空間)があります。Image.FromFileメソッドはビットマップ形式のファイル(アイコンを含む)を読み込んだときはBitmapオブジェクトを、メタファイル形式のファイルを読み込んだときはMetafileオブジェクトを返します。

次の例では、Image.FromFileメソッドが返したデータをBitmapまたはMetafile型にキャストしています。Bitmap型のデータをMetafile型にキャストすることはできませんし、逆もまたできません。

VB.NET
コードを隠すコードを選択
'ビットマップを読み込んで、Bitmap型にキャストする
Dim bmpPath As String = "C:\test.jpg"
Dim bmp As System.Drawing.Bitmap = _
    DirectCast(System.Drawing.Image.FromFile(bmpPath), System.Drawing.Bitmap)

'メタファイルを読み込んで、Metafile型にキャストする
Dim metaPath As String = "C:\test.emf"
Dim meta As System.Drawing.Imaging.Metafile = _
    DirectCast(System.Drawing.Image.FromFile(metaPath), System.Drawing.Imaging.Metafile)
C#
コードを隠すコードを選択
//ビットマップを読み込んで、Bitmap型にキャストする
string bmpPath = @"C:\test.jpg";
System.Drawing.Bitmap bmp =
    (System.Drawing.Bitmap)System.Drawing.Image.FromFile(bmpPath);

//メタファイルを読み込んで、Metafile型にキャストする
string metaPath = @"C:\test.emf";
System.Drawing.Imaging.Metafile meta =
    (System.Drawing.Imaging.Metafile)System.Drawing.Image.FromFile(metaPath);

Bitmapクラスのコンストラクタで読み込む

ビットマップ形式のファイルを読み込むときは、Bitmapクラスのコンストラクタに画像ファイルのパスを指定して読み込むことができます。

VB.NET
コードを隠すコードを選択
'画像ファイルをBitmap型として読み込む
Dim bmp As New System.Drawing.Bitmap("C:\test.jpg")
C#
コードを隠すコードを選択
//画像ファイルをBitmap型として読み込む
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(@"C:\test.jpg");

実はこの方法でメタファイルも読み込むことができます。しかしメタファイルをBitmapとして読み込むと、メモリビットマップイメージ形式に変換される(Image.RawFormatプロパティがImageFormat.MemoryBmpになる)ようです。

Metafileクラスのコンストラクタで読み込む

メタファイル形式のファイルは、Metafileクラスのコンストラクタで読み込むことができます。

VB.NET
コードを隠すコードを選択
'メタファイルを読み込む
Dim meta As New System.Drawing.Imaging.Metafile("C:\test.wmf")
C#
コードを隠すコードを選択
//メタファイルを読み込む
System.Drawing.Imaging.Metafile meta =
    new System.Drawing.Imaging.Metafile(@"C:\test.wmf");

サイズを指定してアイコンファイルを読み込む

アイコンファイルはBitmapオブジェクトとして読み込むことができます。

VB.NET
コードを隠すコードを選択
'アイコンファイルをBitmap型として読み込む
Dim bmp As System.Drawing.Bitmap = _
    DirectCast(System.Drawing.Image.FromFile("C:\test.ico"), System.Drawing.Bitmap)
C#
コードを隠すコードを選択
//アイコンファイルをBitmap型として読み込む
System.Drawing.Bitmap bmp =
    (System.Drawing.Bitmap)System.Drawing.Image.FromFile(@"C:\test.ico");

しかしこれでは、サイズを指定してアイコンファイル内の画像を取得することができません(一番小さいサイズの画像を取得するようですが、確証はありません)。

アイコンファイルはIconオブジェクト(System.Drawing名前空間)として読み込むこともでき、この場合はサイズを指定することができます。ただしIconクラスはImageクラスの派生クラスではありませんので、GDI+の機能を使用して画像の表示や加工等を行う場合は、ToBitmapメソッドでBitmapオブジェクトに変換しなければなりません。

次の例では、アイコンファイル(C:\test.ico)内の48x48ピクセルの画像を取得しています。

VB.NET
コードを隠すコードを選択
'Icon型としてアイコンファイルを読み込み、48x48の画像を取得する
Dim iconPath As String = "C:\test.ico"
Dim ico As New System.Drawing.Icon(iconPath, 48, 48)

'.NET Framework 1.1以下の場合は、次のようにする
'Dim ico0 As New System.Drawing.Icon(iconPath)
'Dim ico As New System.Drawing.Icon(ico0, 48, 48)
'ico0.Dispose()

'Bitmapに変換する
Dim bmp As System.Drawing.Bitmap = ico.ToBitmap()
'変換したBitmapしか使わないならば、元のIconは解放できる
ico.Dispose()

'イメージを表示する
PictureBox1.Image = bmp
C#
コードを隠すコードを選択
//Icon型としてアイコンファイルを読み込み、48x48の画像を取得する
string iconPath = @"C:\test.ico";
System.Drawing.Icon ico = new System.Drawing.Icon(iconPath, 48, 48);

//.NET Framework 1.1以下の場合は、次のようにする
//System.Drawing.Icon ico0 = new System.Drawing.Icon(iconPath);
//System.Drawing.Icon ico = new System.Drawing.Icon(ico0, 48, 48);
//ico0.Dispose();

//Bitmapに変換する
System.Drawing.Bitmap bmp = ico.ToBitmap();
//変換したBitmapしか使わないならば、元のIconは解放できる
ico.Dispose();

//イメージを表示する
PictureBox1.Image = bmp;

なおこの方法では色深度を指定することはできず、現在の画面の色深度に応じた画像となるようです(確証はありません)。

補足:しかしアイコンファイルをBitmapオブジェクトとして読み込む方法では、私が試したところでは、画面が32ビットなのに8ビットのアイコンを取得したため(しかしPixelFormatプロパティはFormat32bppArgb)、どのような規則があるのかよく分かりません。
補足:アイコンファイルを直接Bitmap型として読み込んだときはRawFormatプロパティがImageFormat.Iconになりますが、Icon.ToBitmapメソッドで変換したときはImageFormat.MemoryBmpになります。

256x256サイズのアイコンを取得する

上記の方法では、256x256サイズのアイコンは取得できません。256x256サイズのアイコンを取得する方法は、以下に紹介するページを参考にしてください。

例外OutOfMemoryExceptionがスローされる時

画像を読み込む時に例外OutOfMemoryExceptionがスローされる場合の回避法は、「You receive a "System.OutOfMemoryException" error message when you try to use the Bitmap.FromFile method in the .NET Framework 1.0」にあります。これによると、画像ファイルがこわれているか、画像ファイルにアクセスできるパーミッションがないか、対応していないファイル形式の可能性があるとのことです。詳細はリンク先をご覧ください。

ファイルが削除できなくなる問題の解決法

ここで紹介しているように、画像ファイルのパスを指定してImageオブジェクトを作成した時、そのImageオブジェクトを破棄しないと、画像ファイルはロックされたままになります。そのため、画像ファイルを削除することができません。この問題の解決法は、「表示中の画像ファイルが削除できない問題の解決法」で説明しています。

  • 履歴:
  • 2010/7/16 言葉の間違いを修正。
  • 2011/12/17 「例外OutOfMemoryExceptionがスローされる時」を追加。
  • 2012/7/27 「ファイルが削除できなくなる問題の解決法」を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。