【C#】PictureBoxの使い方完全ガイド|画像表示・サイズ調整・イベント処理までサンプル付きで解説
はじめに
C#でWindowsフォームアプリを作るとき、画像を表示する代表的なコントロールがPictureBoxです。
PictureBoxを使うと、フォーム上にjpg、png、bmpなどの画像を表示したり、画像サイズを調整したり、クリックやマウス操作に応じた処理を実装したりできます。画像ビューア、プロフィール画像表示、商品画像表示、地図表示、簡単な画像編集ツールなど、さまざまな画面で利用されます。
この記事では、C#のWindowsフォームにおけるPictureBoxの基本的な使い方から、画像の読み込み、サイズ調整、イベント処理、描画、エラー対策、実践的なサンプルまでをまとめて解説します。
はじめてPictureBoxを使う方でも理解しやすいように、サンプルコード付きで順番に説明していきます。
1. C#のPictureBoxとは?Windowsフォームで画像を表示する基本
PictureBoxは、C#のWindowsフォームアプリケーションで画像を表示するためのコントロールです。
Visual Studioのフォームデザイナーから簡単に配置でき、プロパティを設定するだけで画像を表示できます。また、コードから画像を読み込んだり、実行中に画像を切り替えたり、クリックイベントやマウスイベントを使って画像に対する操作を実装することも可能です。
1-1. PictureBoxの役割とできること
PictureBoxの主な役割は、フォーム上に画像を表示することです。
代表的には、次のような処理ができます。
画像ファイルを表示する
リソースに登録した画像を表示する
実行中に画像を変更する
画像の表示サイズを調整する
画像クリック時の処理を実行する
マウス操作で座標を取得する
Paintイベントで線や文字を重ねて描画する
ドラッグ&ドロップで画像を読み込む
たとえば、次のようにImageプロパティへ画像を設定すると、PictureBoxに画像を表示できます。
C#pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
このように、PictureBoxは画像表示に関する処理を手軽に実装できる便利なコントロールです。
1-2. PictureBoxを使う主な場面
PictureBoxは、画像を扱うWindowsフォームアプリでよく使われます。
具体的には、次のような場面です。
画像ビューアを作成する
商品画像やプロフィール画像を表示する
サムネイル一覧を表示する
QRコードやバーコード画像を表示する
地図や図面を表示する
画像上のクリック位置を取得する
簡易的な画像編集ツールを作る
カメラ画像やキャプチャ画像を表示する
業務アプリでも、商品管理、社員管理、検査画像表示、帳票プレビューなどでPictureBoxはよく利用されます。
1-3. PictureBoxとImageコントロールの違い
C#のWindowsフォームでは、画像表示には主にPictureBoxを使用します。
一方で、WPFではImageコントロールを使うことが一般的です。名前が似ているため混同しやすいですが、使用するアプリケーションの種類が異なります。
Windowsフォームで画像を表示する場合はPictureBox、WPFで画像を表示する場合はImageコントロールを使う、と考えるとわかりやすいです。
WindowsフォームのPictureBoxは、ImageプロパティやSizeModeプロパティを使って画像表示を制御します。WPFのImageコントロールでは、SourceプロパティやStretchプロパティを使います。
この記事では、WindowsフォームのPictureBoxについて解説します。
1-4. 本記事で作成するサンプルの概要
この記事では、次のようなサンプルを扱います。
フォームに
PictureBoxを配置する画像ファイルを読み込んで表示する
画像の表示方法を
SizeModeで変更するボタンで画像を切り替える
クリックした座標を取得する
ドラッグ&ドロップで画像を表示する
画像上に線やマーカーを描画する
簡易的な画像ビューアを作成する
基本操作から実践的な使い方まで順番に解説するため、必要な部分だけを参考にすることもできます。
2. PictureBoxをフォームに配置する方法
PictureBoxをフォームに配置する方法には、主に2つあります。
1つ目は、Visual Studioのデザイナーから追加する方法です。初心者にはこの方法がわかりやすく、プロパティも画面上で設定できます。
2つ目は、C#のコードからPictureBoxを生成して配置する方法です。実行時に動的にコントロールを追加したい場合に便利です。
2-1. Visual StudioのデザイナーでPictureBoxを追加する
Visual StudioのデザイナーでPictureBoxを追加する手順は次のとおりです。
Windowsフォームアプリケーションのプロジェクトを作成する
フォームデザイナーを開く
ツールボックスから
PictureBoxを探すフォーム上へドラッグ&ドロップする
プロパティウィンドウで名前やサイズを設定する
配置したPictureBoxには、初期状態でpictureBox1のような名前が付けられます。
実務では、用途がわかりやすいようにpicPreviewやpictureBoxPreviewのような名前に変更すると管理しやすくなります。
2-2. コードからPictureBoxを生成して配置する
PictureBoxは、デザイナーを使わずにコードから作成することもできます。
C#using System;
using System.Drawing;
using System.Windows.Forms;
namespace PictureBoxSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PictureBox pictureBox = new PictureBox();
pictureBox.Name = "picSample";
pictureBox.Size = new Size(300, 200);
pictureBox.Location = new Point(20, 20);
pictureBox.BorderStyle = BorderStyle.FixedSingle;
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
this.Controls.Add(pictureBox);
}
}
}
このコードでは、PictureBoxのインスタンスを作成し、サイズや位置などを設定してから、フォームのControlsコレクションに追加しています。
動的に複数の画像枠を作成したい場合や、条件によって表示するコントロールを切り替えたい場合に便利です。
2-3. Name・Size・Locationなど基本プロパティの設定
PictureBoxでよく使う基本プロパティは次のとおりです。
| プロパティ | 説明 |
|---|---|
Name | コントロールの名前 |
Size | 幅と高さ |
Location | フォーム上の表示位置 |
Image | 表示する画像 |
ImageLocation | 読み込む画像ファイルのパス |
SizeMode | 画像の表示方法 |
BorderStyle | 枠線の種類 |
BackColor | 背景色 |
Visible | 表示・非表示 |
Enabled | 操作可能かどうか |
たとえば、コードで基本プロパティを設定する場合は次のように書きます。
C#pictureBox1.Name = "picPreview";
pictureBox1.Size = new Size(400, 300);
pictureBox1.Location = new Point(10, 10);
pictureBox1.BackColor = Color.LightGray;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
SizeはPictureBox自体の表示領域の大きさを指定します。画像そのもののサイズを変更するわけではありません。画像をどのように表示するかは、SizeModeで制御します。
2-4. BorderStyleで枠線を表示する方法
PictureBoxに枠線を付けたい場合は、BorderStyleプロパティを設定します。
C#pictureBox1.BorderStyle = BorderStyle.FixedSingle;
BorderStyleには、主に次の値があります。
| 値 | 説明 |
|---|---|
None | 枠線なし |
FixedSingle | 一重の枠線 |
Fixed3D | 立体的な枠線 |
画像の表示領域をわかりやすくしたい場合は、FixedSingleを設定すると見やすくなります。
C#pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.BackColor = Color.White;
背景色も合わせて設定しておくと、画像が未設定の状態でも領域がわかりやすくなります。
3. PictureBoxに画像を表示する基本操作
PictureBoxに画像を表示する方法はいくつかあります。
代表的な方法は、Imageプロパティ、ImageLocationプロパティ、Loadメソッド、リソース画像の利用です。
用途によって適した方法が異なるため、それぞれの違いを理解しておきましょう。
3-1. Imageプロパティで画像を表示する
もっとも基本的な方法は、ImageプロパティにImageオブジェクトを設定する方法です。
C#pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
このコードでは、指定した画像ファイルを読み込み、pictureBox1に表示しています。
ただし、Image.FromFileで読み込んだ画像は、ファイルがロックされる場合があります。あとで画像ファイルを削除したり上書きしたりする可能性がある場合は、後述するように一度ストリームやコピーを使って読み込む方法がおすすめです。
基本的な表示だけであれば、次のように書けます。
C#private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
}
SizeModeにZoomを指定しておくと、画像の縦横比を保ったままPictureBox内に収めて表示できます。
3-2. ImageLocationプロパティで画像ファイルを読み込む
ImageLocationプロパティに画像ファイルのパスを指定する方法もあります。
C#pictureBox1.ImageLocation = @"C:\Images\sample.jpg";
ImageLocationは、画像の場所を文字列で指定できるため、コードがシンプルになります。
C#pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.ImageLocation = @"C:\Images\sample.png";
ローカルファイルだけでなく、URLを指定して画像を読み込む用途にも使えます。
C#pictureBox1.ImageLocation = "https://example.com/sample.jpg";
ただし、ネットワーク経由の画像は通信状況によって読み込みに失敗する可能性があります。業務アプリでは、例外処理や読み込み中の表示を検討するとよいでしょう。
3-3. Loadメソッドで画像を読み込む
Loadメソッドを使って画像を読み込むこともできます。
C#pictureBox1.Load(@"C:\Images\sample.jpg");
Loadメソッドは、指定した場所から画像を読み込んでPictureBoxに表示します。
C#private void buttonLoad_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Load(@"C:\Images\sample.jpg");
}
ImageLocationを設定する方法と似ていますが、Loadメソッドはその場で読み込みを実行するイメージです。
3-4. リソース画像をPictureBoxに表示する
アプリケーションに画像を組み込んでおきたい場合は、リソース画像を使う方法があります。
Visual Studioでプロジェクトのプロパティを開き、リソースに画像を追加すると、コードから次のように参照できます。
C#pictureBox1.Image = Properties.Resources.sample;
リソース画像を使うと、画像ファイルを別途配布しなくてもアプリケーション内で利用できます。
たとえば、アイコン画像、初期表示画像、エラー画像、ロゴ画像などはリソースに登録しておくと便利です。
C#private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Image = Properties.Resources.logo;
}
リソース画像はアプリケーションに埋め込まれるため、ファイルパスの指定ミスが起きにくいというメリットもあります。
3-5. 実行時に画像を切り替えるサンプル
ボタンをクリックして画像を切り替えるサンプルです。
C#private void buttonImage1_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Image = Image.FromFile(@"C:\Images\image1.jpg");
}
private void buttonImage2_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Image = Image.FromFile(@"C:\Images\image2.jpg");
}
ただし、この書き方では古い画像が解放されずに残る可能性があります。画像を何度も切り替える場合は、古い画像をDisposeしてから新しい画像を設定するのがおすすめです。
C#private void SetImage(string path)
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(path);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
ボタン側では次のように呼び出します。
C#private void buttonImage1_Click(object sender, EventArgs e)
{
SetImage(@"C:\Images\image1.jpg");
}
private void buttonImage2_Click(object sender, EventArgs e)
{
SetImage(@"C:\Images\image2.jpg");
}
画像を頻繁に切り替えるアプリでは、不要な画像を解放する処理を忘れないようにしましょう。
4. PictureBoxの画像サイズを調整する方法
PictureBoxで画像を表示するときに重要なのが、SizeModeプロパティです。
SizeModeを設定することで、画像を原寸で表示するのか、引き伸ばすのか、中央に配置するのか、縦横比を保って拡大縮小するのかを指定できます。
4-1. SizeModeプロパティの種類と違い
PictureBoxSizeModeには、主に次の種類があります。
| 値 | 説明 |
|---|---|
Normal | 画像を左上に原寸表示する |
StretchImage | 画像をPictureBox全体に引き伸ばす |
AutoSize | PictureBoxのサイズを画像サイズに合わせる |
CenterImage | 画像を中央に原寸表示する |
Zoom | 縦横比を保って拡大縮小する |
設定例は次のとおりです。
C#pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
多くの場合は、画像の縦横比を維持できるZoomが使いやすいです。
4-2. Normalで原寸表示する
Normalは、画像を原寸サイズで表示します。
C#pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
画像はPictureBoxの左上を基準に表示されます。画像がPictureBoxより大きい場合、はみ出した部分は表示されません。
Normalは、画像サイズをそのまま確認したい場合や、スクロール可能なビューアと組み合わせる場合に向いています。
4-3. StretchImageで画像を引き伸ばす
StretchImageは、画像をPictureBoxのサイズに合わせて引き伸ばします。
C#pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
PictureBoxの幅と高さに合わせて画像が変形されるため、画像の縦横比が崩れる可能性があります。
たとえば、正方形の画像を横長のPictureBoxに表示すると、横に引き伸ばされて見えます。
画像の比率が崩れてもよい場合や、背景画像のように領域全体を埋めたい場合に使えます。
4-4. AutoSizeで画像サイズに合わせる
AutoSizeは、PictureBox自体のサイズを画像サイズに合わせます。
C#pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
画像が大きい場合、PictureBoxも大きくなります。そのため、フォームからはみ出す可能性があります。
AutoSizeは、画像の原寸サイズに合わせてコントロールを表示したい場合に便利です。
ただし、ユーザーが選択する画像サイズが不明な場合は、画面レイアウトが崩れる可能性があるため注意しましょう。
4-5. CenterImageで中央に表示する
CenterImageは、画像をPictureBoxの中央に原寸表示します。
C#pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
画像がPictureBoxより小さい場合は中央に配置されます。画像が大きい場合は、中央部分が表示され、はみ出した部分は見えません。
ロゴやアイコンのように、小さな画像を中央に表示したい場合に向いています。
C#pictureBox1.BackColor = Color.White;
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
背景色や枠線を設定しておくと、中央配置の見た目がわかりやすくなります。
4-6. Zoomで縦横比を保って表示する
Zoomは、画像の縦横比を保ったまま、PictureBox内に収まるように拡大または縮小して表示します。
C#pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
画像が変形されないため、写真やイラストを自然に表示できます。
PictureBoxの領域と画像の縦横比が異なる場合は、上下または左右に余白ができます。
画像ビューアやプレビュー画面では、基本的にZoomを使うのがおすすめです。
4-7. 用途別におすすめのSizeModeを選ぶ
SizeModeは用途に応じて選びましょう。
| 用途 | おすすめのSizeMode |
|---|---|
| 写真を自然に表示したい | Zoom |
| 画像を原寸で確認したい | Normal |
| 領域全体に画像を表示したい | StretchImage |
| 画像サイズに合わせて表示領域を変えたい | AutoSize |
| 小さなアイコンやロゴを中央表示したい | CenterImage |
迷った場合は、まずZoomを使うとよいでしょう。縦横比を保ったまま表示できるため、多くの場面で自然な見た目になります。
5. PictureBoxで画像ファイルを選択して表示する
実際のアプリでは、ユーザーが画像ファイルを選択し、その画像をPictureBoxに表示するケースがよくあります。
この場合は、OpenFileDialogを使うと簡単です。
5-1. OpenFileDialogで画像ファイルを選択する
OpenFileDialogは、ファイル選択ダイアログを表示するためのクラスです。
C#OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "画像ファイルを選択してください";
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (dialog.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(dialog.FileName);
}
このコードをボタンのクリックイベントに書くと、ボタンを押したときに画像ファイルを選択できます。
5-2. jpg・png・bmpなど対応形式を指定する
OpenFileDialogでは、Filterプロパティを使って選択できるファイル形式を指定できます。
C#dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif|すべてのファイル|*.*";
この指定では、ダイアログ上で画像ファイルとすべてのファイルを切り替えられます。
よりわかりやすく分けたい場合は、次のように指定できます。
C#dialog.Filter = "JPEGファイル|*.jpg;*.jpeg|PNGファイル|*.png|BMPファイル|*.bmp|すべてのファイル|*.*";
ユーザーが誤って画像以外のファイルを選択しないように、対応形式を指定しておくと親切です。
5-3. 選択した画像をPictureBoxに表示するサンプル
次のサンプルでは、ボタンをクリックすると画像ファイルを選択し、PictureBoxに表示します。
C#private void buttonOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "画像ファイルを選択してください";
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif|すべてのファイル|*.*";
if (dialog.ShowDialog() == DialogResult.OK)
{
SetPictureBoxImage(dialog.FileName);
}
}
}
private void SetPictureBoxImage(string filePath)
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(filePath);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
画像を切り替える前に古い画像をDisposeしているため、メモリ使用量の増加を防ぎやすくなります。
5-4. 存在しないファイルや読み込み失敗時の例外処理
画像ファイルを読み込むときは、ファイルが存在しない、画像形式が不正、アクセス権限がないなどの理由でエラーが発生することがあります。
安定したアプリにするためには、例外処理を入れておきましょう。
C#private void SetPictureBoxImage(string filePath)
{
try
{
if (!File.Exists(filePath))
{
MessageBox.Show("指定されたファイルが存在しません。");
return;
}
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(filePath);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
catch (OutOfMemoryException)
{
MessageBox.Show("画像ファイルとして読み込めませんでした。");
}
catch (Exception ex)
{
MessageBox.Show("画像の読み込みに失敗しました。\n" + ex.Message);
}
}
Image.FromFileでは、画像形式が不正な場合でもOutOfMemoryExceptionが発生することがあります。そのため、画像読み込み処理では例外処理を用意しておくと安心です。
また、File.Existsを使う場合は、先頭に次の名前空間を追加します。
C#using System.IO;
6. PictureBoxのイベント処理を使いこなす
PictureBoxでは、クリック、ダブルクリック、マウス移動、ドラッグ&ドロップなどのイベントを扱えます。
イベント処理を使うことで、画像を表示するだけでなく、ユーザー操作に応じた処理を実装できます。
6-1. Clickイベントで画像クリックを検出する
Clickイベントを使うと、PictureBoxがクリックされたことを検出できます。
C#private void pictureBox1_Click(object sender, EventArgs e)
{
MessageBox.Show("画像がクリックされました。");
}
Visual StudioのデザイナーでPictureBoxを選択し、イベント一覧からClickをダブルクリックすると、イベントハンドラを自動生成できます。
コードでイベントを登録する場合は、次のように書きます。
C#pictureBox1.Click += pictureBox1_Click;
クリック時に画像を切り替えたり、詳細画面を開いたりする処理によく使います。
6-2. MouseDown・MouseMove・MouseUpでマウス操作を処理する
より細かいマウス操作を扱いたい場合は、MouseDown、MouseMove、MouseUpを使います。
C#private bool isDragging = false;
private Point startPoint;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
startPoint = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Text = $"開始位置: {startPoint}, 現在位置: {e.Location}";
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
このように、マウスの押下、移動、解放を組み合わせることで、ドラッグ操作を実装できます。
画像上で矩形選択をしたい場合や、マーカーを移動したい場合に便利です。
6-3. DoubleClickイベントで画像を拡大表示する
DoubleClickイベントを使うと、画像がダブルクリックされたときの処理を実装できます。
たとえば、ダブルクリックでSizeModeを切り替えるサンプルは次のとおりです。
C#private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
if (pictureBox1.SizeMode == PictureBoxSizeMode.Zoom)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
}
else
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
}
このサンプルでは、通常はZoomで全体表示し、ダブルクリックするとNormalで原寸表示に切り替えます。
簡易画像ビューアの拡大表示機能として使えます。
6-4. DragDropイベントで画像をドラッグ&ドロップ表示する
PictureBoxに画像ファイルをドラッグ&ドロップして表示することもできます。
まず、AllowDropをtrueに設定します。
C#pictureBox1.AllowDrop = true;
次に、DragEnterイベントとDragDropイベントを実装します。
C#private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files.Length > 0)
{
SetPictureBoxImage(files[0]);
}
}
画像ファイルをPictureBoxへ直接ドロップできるため、ユーザーにとって使いやすい画面になります。
6-5. イベント処理のサンプルコード
クリック、座標取得、ダブルクリック、ドラッグ&ドロップをまとめたサンプルです。
C#public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.AllowDrop = true;
pictureBox1.Click += pictureBox1_Click;
pictureBox1.MouseDown += pictureBox1_MouseDown;
pictureBox1.DoubleClick += pictureBox1_DoubleClick;
pictureBox1.DragEnter += pictureBox1_DragEnter;
pictureBox1.DragDrop += pictureBox1_DragDrop;
}
private void pictureBox1_Click(object sender, EventArgs e)
{
MessageBox.Show("PictureBoxがクリックされました。");
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
MessageBox.Show($"クリック座標: X={e.X}, Y={e.Y}");
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
pictureBox1.SizeMode =
pictureBox1.SizeMode == PictureBoxSizeMode.Zoom
? PictureBoxSizeMode.Normal
: PictureBoxSizeMode.Zoom;
}
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files.Length > 0)
{
SetPictureBoxImage(files[0]);
}
}
private void SetPictureBoxImage(string filePath)
{
try
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(filePath);
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
catch (Exception ex)
{
MessageBox.Show("画像の読み込みに失敗しました。\n" + ex.Message);
}
}
}
このように、PictureBoxは画像表示だけでなく、ユーザー操作を受け取るコントロールとしても活用できます。
7. PictureBoxに描画や加工を行う方法
PictureBoxでは、画像の上に線、矩形、文字、マーカーなどを描画できます。
描画処理には、主にPaintイベントとGraphicsオブジェクトを使用します。
7-1. Paintイベントで図形や文字を重ねて描画する
Paintイベントは、コントロールが再描画されるタイミングで呼び出されます。
PictureBoxに図形や文字を重ねて描画したい場合は、Paintイベントを使うのが基本です。
C#private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Red, 50, 50, 100, 80);
e.Graphics.DrawString("Sample", this.Font, Brushes.Blue, 60, 60);
}
このコードでは、PictureBox上に赤い矩形と青い文字を描画しています。
デザイナーでPaintイベントを登録するか、コードで次のように登録します。
C#pictureBox1.Paint += pictureBox1_Paint;
7-2. Graphicsを使って線や矩形を描く
Graphicsを使うと、線、矩形、円、文字などを描画できます。
C#private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawLine(Pens.Red, 10, 10, 200, 100);
g.DrawRectangle(Pens.Blue, 50, 50, 120, 80);
g.DrawEllipse(Pens.Green, 100, 100, 80, 80);
}
塗りつぶした矩形を描画したい場合は、FillRectangleを使います。
C#e.Graphics.FillRectangle(Brushes.Yellow, 20, 20, 100, 50);
文字を描画する場合は、DrawStringを使います。
C#e.Graphics.DrawString("画像プレビュー", this.Font, Brushes.Black, 10, 10);
7-3. 画像上にマーカーを表示する
画像クリック位置にマーカーを表示するサンプルです。
C#private Point? markerPoint = null;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
markerPoint = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (markerPoint.HasValue)
{
Point p = markerPoint.Value;
int size = 10;
e.Graphics.DrawEllipse(
Pens.Red,
p.X - size / 2,
p.Y - size / 2,
size,
size);
e.Graphics.DrawLine(Pens.Red, p.X - 8, p.Y, p.X + 8, p.Y);
e.Graphics.DrawLine(Pens.Red, p.X, p.Y - 8, p.X, p.Y + 8);
}
}
MouseDownでクリック位置を保存し、Invalidateで再描画を要求しています。再描画時にPaintイベントが呼ばれ、保存した座標にマーカーが描画されます。
7-4. 描画内容を更新するInvalidateメソッドの使い方
Invalidateメソッドは、コントロールの再描画を要求するメソッドです。
描画に使う座標や状態が変わった場合は、Invalidateを呼び出してPaintイベントを再実行させます。
C#pictureBox1.Invalidate();
たとえば、クリックした位置にマーカーを表示する場合、クリックイベント内で座標を保存したあとにInvalidateを呼びます。
C#private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
markerPoint = e.Location;
pictureBox1.Invalidate();
}
Paintイベントの中で直接状態を変更し続けるのではなく、必要な情報をフィールドに保存し、Invalidateで描画を更新するのが基本です。
7-5. PictureBoxで簡易ビューアを作るサンプル
画像を表示し、クリックした位置にマーカーを描画する簡易ビューアのサンプルです。
C#using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace PictureBoxViewerSample
{
public partial class Form1 : Form
{
private Point? markerPoint = null;
public Form1()
{
InitializeComponent();
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.BackColor = Color.White;
pictureBox1.MouseDown += pictureBox1_MouseDown;
pictureBox1.Paint += pictureBox1_Paint;
}
private void buttonOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (dialog.ShowDialog() == DialogResult.OK)
{
LoadImage(dialog.FileName);
markerPoint = null;
pictureBox1.Invalidate();
}
}
}
private void LoadImage(string path)
{
try
{
if (!File.Exists(path))
{
MessageBox.Show("ファイルが存在しません。");
return;
}
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(path);
}
catch (Exception ex)
{
MessageBox.Show("画像を読み込めませんでした。\n" + ex.Message);
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
markerPoint = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (markerPoint.HasValue)
{
Point p = markerPoint.Value;
e.Graphics.DrawEllipse(Pens.Red, p.X - 5, p.Y - 5, 10, 10);
e.Graphics.DrawLine(Pens.Red, p.X - 10, p.Y, p.X + 10, p.Y);
e.Graphics.DrawLine(Pens.Red, p.X, p.Y - 10, p.X, p.Y + 10);
}
}
}
}
このサンプルを応用すると、検査画像に印を付けるアプリや、画像上の位置を確認するツールを作成できます。
8. PictureBox使用時によくあるエラーと対処法
PictureBoxを使っていると、画像が表示されない、ファイルがロックされる、メモリ使用量が増えるなどの問題が発生することがあります。
ここでは、よくある原因と対処法を紹介します。
8-1. 画像が表示されない原因と確認ポイント
画像が表示されない場合は、次の点を確認しましょう。
ファイルパスが正しいか
画像ファイルが存在するか
画像形式が対応しているか
Imageプロパティに正しく設定されているかPictureBoxのサイズが小さすぎないかVisibleがfalseになっていないか他のコントロールの背面に隠れていないか
例外が発生していないか
確認用のコードとして、まずは次のようにファイル存在チェックを入れると原因を特定しやすくなります。
C#string path = @"C:\Images\sample.jpg";
if (File.Exists(path))
{
pictureBox1.Image = Image.FromFile(path);
}
else
{
MessageBox.Show("画像ファイルが見つかりません。");
}
また、PictureBoxのサイズが0に近い場合や、別のコントロールに隠れている場合も表示されません。
8-2. ファイルパス指定ミスを防ぐ方法
ファイルパスの指定ミスは、PictureBoxで画像が表示されない原因としてよくあります。
C#では、通常の文字列でバックスラッシュを書く場合、\\のようにエスケープする必要があります。
C#pictureBox1.Image = Image.FromFile("C:\\Images\\sample.jpg");
または、逐語的文字列リテラルを使うと、次のように書けます。
C#pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
相対パスを使う場合は、実行ファイルの場所を基準に解釈される点に注意しましょう。
C#string path = Path.Combine(Application.StartupPath, "Images", "sample.jpg");
pictureBox1.Image = Image.FromFile(path);
Path.Combineを使うと、フォルダ区切り文字のミスを防ぎやすくなります。
8-3. NullReferenceExceptionが発生する原因
NullReferenceExceptionは、値がnullのオブジェクトを使おうとしたときに発生します。
PictureBoxでよくある例は、画像が設定されていない状態でpictureBox1.Image.Widthなどにアクセスするケースです。
C#int width = pictureBox1.Image.Width;
Imageがnullの場合、このコードはエラーになります。
対処するには、nullチェックを行います。
C#if (pictureBox1.Image != null)
{
int width = pictureBox1.Image.Width;
int height = pictureBox1.Image.Height;
MessageBox.Show($"画像サイズ: {width} x {height}");
}
else
{
MessageBox.Show("画像が設定されていません。");
}
画像を扱う処理では、pictureBox1.Image != nullを確認してから処理する習慣をつけましょう。
8-4. 画像ファイルがロックされる問題の対処法
Image.FromFileで画像を読み込むと、画像ファイルがロックされることがあります。
その結果、画像を表示中にファイルを削除したり上書きしたりしようとすると、失敗する場合があります。
ファイルロックを避けたい場合は、画像を一度読み込んでコピーを作成する方法が有効です。
C#private Image LoadImageWithoutLock(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Image img = Image.FromStream(fs))
{
return new Bitmap(img);
}
}
使用例は次のとおりです。
C#if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = LoadImageWithoutLock(@"C:\Images\sample.jpg");
この方法では、ファイルストリームを閉じたあともBitmapのコピーを使って表示できます。
8-5. メモリリークを防ぐDisposeの使い方
画像を何度も読み込むアプリでは、古い画像を解放しないとメモリ使用量が増える可能性があります。
PictureBox.Imageに設定した画像が不要になったら、Disposeで解放しましょう。
C#if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
フォームを閉じるときにも画像を解放しておくと安心です。
C#private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
}
画像を切り替える処理では、新しい画像を設定する前に古い画像を解放するのが基本です。
C#private void ChangeImage(string path)
{
Image newImage = LoadImageWithoutLock(path);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = newImage;
}
先に新しい画像の読み込みに成功してから古い画像を破棄すると、読み込み失敗時に現在の画像を残せます。
8-6. 大きな画像を表示すると重い場合の対策
高解像度の画像をそのままPictureBoxに表示すると、メモリ使用量が増えたり、表示が重くなったりすることがあります。
対策としては、次の方法があります。
表示用に縮小画像を作成する
必要以上に大きな画像を読み込まない
サムネイルを使う
画像を切り替えるときに古い画像をDisposeする
UIスレッドで重い処理をしすぎない
表示用に縮小画像を作るサンプルです。
C#private Image CreateResizedImage(Image source, int maxWidth, int maxHeight)
{
double scaleX = (double)maxWidth / source.Width;
double scaleY = (double)maxHeight / source.Height;
double scale = Math.Min(scaleX, scaleY);
int newWidth = (int)(source.Width * scale);
int newHeight = (int)(source.Height * scale);
Bitmap bitmap = new Bitmap(newWidth, newHeight);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(source, 0, 0, newWidth, newHeight);
}
return bitmap;
}
使用例です。
C#using (Image original = Image.FromFile(@"C:\Images\large.jpg"))
{
pictureBox1.Image = CreateResizedImage(original, 800, 600);
}
大きな画像を扱う場合は、原寸画像をそのまま表示するのではなく、用途に合わせて縮小してから表示するとパフォーマンスを改善できます。
9. PictureBoxの実践サンプル集
ここからは、PictureBoxを使った実践的なサンプルを紹介します。
基本操作を組み合わせることで、画像ビューアやスライドショーのようなアプリを作ることができます。
9-1. ボタン操作で画像を表示・変更するサンプル
ボタンを押すたびに画像を変更するサンプルです。
C#private void buttonOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (dialog.ShowDialog() == DialogResult.OK)
{
ChangeImage(dialog.FileName);
}
}
}
private void ChangeImage(string path)
{
try
{
Image newImage = LoadImageWithoutLock(path);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = newImage;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
catch (Exception ex)
{
MessageBox.Show("画像の表示に失敗しました。\n" + ex.Message);
}
}
private Image LoadImageWithoutLock(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Image img = Image.FromStream(fs))
{
return new Bitmap(img);
}
}
このサンプルでは、画像ファイルのロックを避けるためにLoadImageWithoutLockメソッドを使っています。
9-2. 画像を拡大・縮小表示するサンプル
PictureBox自体のサイズを変更することで、画像の表示サイズを拡大・縮小できます。
C#private double zoomRate = 1.0;
private void buttonZoomIn_Click(object sender, EventArgs e)
{
zoomRate += 0.1;
ApplyZoom();
}
private void buttonZoomOut_Click(object sender, EventArgs e)
{
zoomRate -= 0.1;
if (zoomRate < 0.1)
{
zoomRate = 0.1;
}
ApplyZoom();
}
private void ApplyZoom()
{
if (pictureBox1.Image == null)
{
return;
}
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Width = (int)(pictureBox1.Image.Width * zoomRate);
pictureBox1.Height = (int)(pictureBox1.Image.Height * zoomRate);
}
このサンプルでは、zoomRateに応じてPictureBoxのサイズを変更しています。
スクロールしながら拡大画像を見たい場合は、PictureBoxをPanelの中に配置し、Panel.AutoScrollをtrueにすると便利です。
C#panel1.AutoScroll = true;
panel1.Controls.Add(pictureBox1);
9-3. 画像をクリックして座標を取得するサンプル
画像をクリックした位置の座標を取得するサンプルです。
C#private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
label1.Text = $"クリック座標: X={e.X}, Y={e.Y}";
}
ただし、SizeModeがZoomの場合、取得できる座標はPictureBox上の座標です。画像そのものの座標とは異なる場合があります。
Zoom表示時に画像上の実座標へ変換したい場合は、画像の表示領域を考慮する必要があります。
C#private Point? ConvertToImagePoint(Point pictureBoxPoint)
{
if (pictureBox1.Image == null)
{
return null;
}
Image img = pictureBox1.Image;
float imageRatio = (float)img.Width / img.Height;
float boxRatio = (float)pictureBox1.Width / pictureBox1.Height;
int drawWidth;
int drawHeight;
int offsetX;
int offsetY;
if (imageRatio > boxRatio)
{
drawWidth = pictureBox1.Width;
drawHeight = (int)(pictureBox1.Width / imageRatio);
offsetX = 0;
offsetY = (pictureBox1.Height - drawHeight) / 2;
}
else
{
drawHeight = pictureBox1.Height;
drawWidth = (int)(pictureBox1.Height * imageRatio);
offsetX = (pictureBox1.Width - drawWidth) / 2;
offsetY = 0;
}
if (pictureBoxPoint.X < offsetX ||
pictureBoxPoint.X > offsetX + drawWidth ||
pictureBoxPoint.Y < offsetY ||
pictureBoxPoint.Y > offsetY + drawHeight)
{
return null;
}
int imageX = (int)((pictureBoxPoint.X - offsetX) * img.Width / (float)drawWidth);
int imageY = (int)((pictureBoxPoint.Y - offsetY) * img.Height / (float)drawHeight);
return new Point(imageX, imageY);
}
使用例です。
C#private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Point? imagePoint = ConvertToImagePoint(e.Location);
if (imagePoint.HasValue)
{
label1.Text = $"画像座標: X={imagePoint.Value.X}, Y={imagePoint.Value.Y}";
}
else
{
label1.Text = "画像の外側がクリックされました。";
}
}
画像上の正確な座標を使いたい場合は、SizeModeによる表示方法を考慮しましょう。
9-4. 複数の画像を切り替える簡易スライドショー
複数の画像を順番に表示する簡易スライドショーのサンプルです。
フォームにPictureBox、Button、Timerを配置して使います。
C#private string[] imageFiles;
private int currentIndex = 0;
private void Form1_Load(object sender, EventArgs e)
{
imageFiles = new string[]
{
@"C:\Images\photo1.jpg",
@"C:\Images\photo2.jpg",
@"C:\Images\photo3.jpg"
};
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
timer1.Interval = 2000;
timer1.Tick += timer1_Tick;
ShowImage();
}
private void buttonStart_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void buttonStop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void timer1_Tick(object sender, EventArgs e)
{
currentIndex++;
if (currentIndex >= imageFiles.Length)
{
currentIndex = 0;
}
ShowImage();
}
private void ShowImage()
{
if (imageFiles == null || imageFiles.Length == 0)
{
return;
}
string path = imageFiles[currentIndex];
if (!File.Exists(path))
{
return;
}
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
pictureBox1.Image = Image.FromFile(path);
}
Timerを使うことで、一定間隔で画像を切り替えられます。
実用的にする場合は、フォルダ内の画像を自動取得する処理を追加すると便利です。
C#imageFiles = Directory.GetFiles(
@"C:\Images",
"*.*")
.Where(file =>
file.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ||
file.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase) ||
file.EndsWith(".png", StringComparison.OrdinalIgnoreCase) ||
file.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase))
.ToArray();
このコードを使う場合は、次の名前空間を追加します。
C#using System.Linq;
using System.IO;
9-5. PictureBoxを使った画像ビューアの作成例
最後に、画像を開く、拡大表示、全体表示を切り替える簡単な画像ビューアの例です。
C#using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace SimpleImageViewer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.BackColor = Color.White;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
private void buttonOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (dialog.ShowDialog() == DialogResult.OK)
{
LoadImage(dialog.FileName);
}
}
}
private void buttonZoom_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
private void buttonNormal_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
}
private void buttonCenter_Click(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
}
private void LoadImage(string path)
{
try
{
Image newImage = LoadImageWithoutLock(path);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = newImage;
}
catch (Exception ex)
{
MessageBox.Show("画像を読み込めませんでした。\n" + ex.Message);
}
}
private Image LoadImageWithoutLock(string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Image img = Image.FromStream(fs))
{
return new Bitmap(img);
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
}
}
}
このサンプルでは、画像を安全に読み込み、SizeModeをボタンで切り替えられるようにしています。
機能を追加すれば、次のような画像ビューアに発展させることもできます。
前へ・次へボタン
フォルダ内画像の一覧表示
サムネイル表示
画像の回転
画像上の座標表示
ドラッグ&ドロップ読み込み
PictureBoxはシンプルなコントロールですが、工夫次第で実用的な画像表示アプリを作成できます。
10. PictureBoxを使う際のベストプラクティス
PictureBoxを使うときは、ただ画像を表示するだけでなく、保守性や安定性も意識することが大切です。
特に、画像読み込み、例外処理、メモリ解放、表示サイズの設計は重要です。
10-1. 画像読み込み処理をわかりやすく分離する
画像読み込み処理は、ボタンイベントの中に直接書きすぎないようにしましょう。
処理をメソッドに分けると、コードが読みやすくなり、再利用しやすくなります。
C#private void LoadImageToPictureBox(string path)
{
Image newImage = LoadImageWithoutLock(path);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
pictureBox1.Image = newImage;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
ボタンイベントでは、メソッドを呼び出すだけにします。
C#private void buttonOpen_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "画像ファイル|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (dialog.ShowDialog() == DialogResult.OK)
{
LoadImageToPictureBox(dialog.FileName);
}
}
}
このように分けると、ドラッグ&ドロップやスライドショーでも同じ読み込み処理を使えます。
10-2. 例外処理を入れて安定したアプリにする
画像ファイルは、必ず読み込めるとは限りません。
ファイルが削除されている、アクセス権限がない、壊れている、画像形式ではないなど、さまざまな理由でエラーが発生します。
そのため、画像読み込み処理にはtry-catchを入れておきましょう。
C#private void SafeLoadImage(string path)
{
try
{
if (!File.Exists(path))
{
MessageBox.Show("ファイルが見つかりません。");
return;
}
LoadImageToPictureBox(path);
}
catch (Exception ex)
{
MessageBox.Show("画像の読み込み中にエラーが発生しました。\n" + ex.Message);
}
}
エラーが発生してもアプリが突然終了しないようにすることが大切です。
10-3. 画像サイズと表示サイズを意識する
画像のサイズとPictureBoxの表示サイズは別物です。
たとえば、4000×3000ピクセルの画像を300×200のPictureBoxに表示する場合、見た目は小さくても内部的には大きな画像を保持しているため、メモリを多く使用します。
プレビューだけが目的なら、表示用に縮小画像を作成することを検討しましょう。
C#private Image CreateThumbnailImage(string path, int width, int height)
{
using (Image original = Image.FromFile(path))
{
Bitmap thumbnail = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(thumbnail))
{
g.DrawImage(original, 0, 0, width, height);
}
return thumbnail;
}
}
ただし、このコードでは指定した幅と高さに合わせて描画するため、縦横比を厳密に保ちたい場合は比率計算を追加する必要があります。
写真を自然に表示したい場合は、SizeModeにZoomを設定するのが基本です。
C#pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
10-4. 不要になった画像は適切に解放する
PictureBoxで画像を扱うときに特に重要なのが、不要になった画像の解放です。
画像を切り替えるたびに新しいImageを設定していると、古い画像が残り続けてメモリ使用量が増えることがあります。
新しい画像を設定する前に、古い画像をDisposeしましょう。
C#private void ReleasePictureBoxImage()
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
}
}
画像を変更するときは次のように使います。
C#ReleasePictureBoxImage();
pictureBox1.Image = Image.FromFile(@"C:\Images\sample.jpg");
フォーム終了時にも解放しておくと安全です。
C#private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
ReleasePictureBoxImage();
}
PictureBoxは手軽に画像を表示できる反面、画像ファイルやメモリを扱うため、リソース管理を意識することが大切です。
まとめ
C#のWindowsフォームで画像を表示するなら、PictureBoxはもっとも基本的で使いやすいコントロールです。
ImageプロパティやImageLocation、Loadメソッドを使えば画像を簡単に表示できます。また、SizeModeを設定することで、原寸表示、引き伸ばし、中央表示、縦横比を保った拡大縮小など、用途に応じた表示方法を選べます。
実際のアプリでは、OpenFileDialogで画像ファイルを選択して表示したり、クリックイベントで座標を取得したり、ドラッグ&ドロップで画像を読み込んだりする場面が多くあります。さらに、PaintイベントとGraphicsを使えば、画像上に線や文字、マーカーを重ねて描画することも可能です。
一方で、画像が表示されない、ファイルパスが間違っている、NullReferenceExceptionが発生する、画像ファイルがロックされる、メモリ使用量が増えるといったトラブルも起こりやすいです。
安定したアプリを作るためには、次のポイントを意識しましょう。
画像の読み込み処理をメソッドに分離する
ファイル存在チェックと例外処理を入れる
SizeModeを用途に応じて選ぶ大きな画像は必要に応じて縮小する
不要になった画像は
Disposeで解放するファイルロックを避けたい場合は画像をコピーして読み込む
PictureBoxの基本を理解しておくと、画像ビューア、商品画像表示、検査画像確認ツール、簡易編集アプリなど、さまざまなWindowsフォームアプリを作成できます。
まずはPictureBoxに画像を表示する簡単なサンプルから始め、サイズ調整、イベント処理、描画処理へと少しずつ応用していきましょう。

