Visual C をシャープにして、データベースから PictureBox コントロールに画像を直接コピーする
この記事では、データベースに格納されているイメージを Windows フォームの PictureBox コントロールに直接コピーする方法について説明します。画像をファイルに保存する必要はありません。
元の製品バージョン: Visual C#
元の KB 番号: 317701
この記事では、データベースに格納されているイメージを Windows フォームの PictureBox コントロールに直接コピーする方法について説明します。画像をファイルに保存する必要はありません。
Visual Basic 6.0 では、バイナリ ラージ オブジェクト {BLOB) データをファイルに保存する中間手順なしで、PictureBox コントロール内のデータベースの画像を表示する唯一の方法は、PictureBox を ActiveX データ オブジェクト (ADO) データ コントロールや Recordset などのデータ ソースにバインドすることです。 LoadPicture ステートメントで使用するためにイメージをファイルに保存せずに、プログラムによって BLOB をコントロールに読み込む方法はありません (データ バインディングを使用しない)。
この記事では、System.IO
基本クラスのMemoryStream
オブジェクトを使用して、データベースから PictureBox コントロールに直接イメージ データをコピーします。
次の一覧では、必要なハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、およびサービス パックの推奨される概要を示します。
- 互換性のある Windows オペレーティング システムにインストールされた Visual Studio .NET
- SQL Server の使用可能なインスタンスまたはテストに使用できる Access データベース
この記事では、次のトピックについて理解していることを前提としています。
- Visual C# .NET Windows フォーム アプリケーション
- データベース内のバイナリ ラージ オブジェクト (BLOB) ストレージ
- データ アクセスの ADO.NET
次の構造の SQL Server または Access テーブルを作成します。
CREATE TABLE BLOBTest ( BLOBID INT IDENTITY NOT NULL, BLOBData IMAGE NOT NULL )
Visual Studio .NET を開き、新しい Visual C# Windows アプリケーション プロジェクトを作成します。
ツールボックスから既定の Form1 に PictureBox コントロールと 2 つの Button コントロールを追加します。
Button1
のText
プロパティを File から Database に設定しButton2
のText
プロパティを Database を PictureBox に設定。フォームのコード モジュールの先頭に次の using ステートメントを挿入します。
using System.Data.SqlClient; using System.IO; using System.Drawing.Imaging;
パブリック クラス Form1 内のデータベース 接続文字列に次の宣言を追加します。宣言を
System.Windows.Forms.Form class
し、必要に応じて接続文字列を調整します。String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
Button1
のClick
イベント プロシージャに次のコードを挿入します (File to Database)。 必要に応じて、使用可能なサンプル イメージ ファイルへのファイル パスを調整します。 このコードは、(FileStream
オブジェクトを使用して) ディスクからByte
配列にイメージ ファイルを読み取り、パラメーター化された Command オブジェクトを使用してデータベースにデータを挿入します。try { SqlConnection cn = new SqlConnection(strCn); SqlCommand cmd = new SqlCommand("INSERT INTO BLOBTest (BLOBData) VALUES (@BLOBData)", cn); String strBLOBFilePath = @"C:\blue hills.jpg";//Modify this path as needed. //Read jpg into file stream, and from there into Byte array. FileStream fsBLOBFile = new FileStream(strBLOBFilePath,FileMode.Open, FileAccess.Read); Byte[] bytBLOBData = new Byte[fsBLOBFile.Length]; fsBLOBFile.Read(bytBLOBData, 0, bytBLOBData.Length); fsBLOBFile.Close(); //Create parameter for insert command and add to SqlCommand object. SqlParameter prm = new SqlParameter("@BLOBData", SqlDbType.VarBinary, bytBLOBData.Length, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, bytBLOBData); cmd.Parameters.Add(prm); //Open connection, execute query, and close connection. cn.Open(); cmd.ExecuteNonQuery(); cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
Button2
のClick
イベント プロシージャに次のコードを挿入します (Database to PictureBox)。 このコードは、データベース内のBLOBTest
テーブルから行をDataSet
に取得し、最後に追加した画像をByte
配列にコピーしてから、MemoryStream
オブジェクトにコピーした後、PictureBox コントロールのImage
プロパティにMemoryStream
を読み込みます。try { SqlConnection cn = new SqlConnection(strCn); cn.Open(); //Retrieve BLOB from database into DataSet. SqlCommand cmd = new SqlCommand("SELECT BLOBID, BLOBData FROM BLOBTest ORDER BY BLOBID", cn); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds, "BLOBTest"); int c = ds.Tables["BLOBTest"].Rows.Count; if(c>0) { //BLOB is read into Byte array, then used to construct MemoryStream, //then passed to PictureBox. Byte[] byteBLOBData = new Byte[0]; byteBLOBData = (Byte[])(ds.Tables["BLOBTest"].Rows[c - 1]["BLOBData"]); MemoryStream stmBLOBData = new MemoryStream(byteBLOBData); pictureBox1.Image= Image.FromStream(stmBLOBData); } cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
F5 キーを押して、プロジェクトをコンパイルし、実行します。
[データベースへのファイル] ボタンをクリックして、少なくとも 1 つのサンプル イメージをデータベースに読み込みます。
[ Database to PictureBox ] ボタンをクリックして、保存した画像を PictureBox コントロールに表示します。
PictureBox コントロールから直接データベースに画像を挿入できるようにする場合は、3 つ目の Button コントロールを追加し、その
Click
イベント プロシージャに次のコードを挿入します。 このコードは、PictureBox コントロールから画像データをMemoryStream
オブジェクトに取得し、MemoryStream
をByte
配列にコピーした後、パラメーター化された Command オブジェクトを使用してByte
配列をデータベースに保存します。try { SqlConnection cn = new SqlConnection(strCn); SqlCommand cmd = new SqlCommand("INSERT INTO BLOBTest (BLOBData) VALUES (@BLOBData)", cn); //Save image from PictureBox into MemoryStream object. MemoryStream ms = new MemoryStream(); pictureBox1.Image.Save(ms, ImageFormat.Jpeg); //Read from MemoryStream into Byte array. Byte[] bytBLOBData = new Byte[ms.Length]; ms.Position = 0; ms.Read(bytBLOBData, 0, Convert.ToInt32(ms.Length)); //Create parameter for insert statement that contains image. SqlParameter prm = new SqlParameter("@BLOBData", SqlDbType.VarBinary, bytBLOBData.Length, ParameterDirection.Input, false, 0, 0,null, DataRowVersion.Current, bytBLOBData); cmd.Parameters.Add(prm); cn.Open(); cmd.ExecuteNonQuery(); cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
プロジェクトを実行します。 [ Database to PictureBox ] ボタンをクリックして、以前に保存した画像を PictureBox コントロールに表示します。 新しく追加したボタンをクリックして、PictureBox からデータベースに画像を保存します。 次に、 Database to PictureBox ボタンをもう一度クリックして、イメージが正しく保存されたことを確認します。
このテストは、Access と SQL Server で配布されたサンプル Northwind データベースの Employees テーブルの [写真] 列では機能しません。 [写真] 列に格納されているビットマップ イメージは、Visual Basic 6.0 OLE コンテナー コントロールによって作成されたヘッダー情報でラップされます。
Access データベースを使用してこのコードをテストする必要がある場合は、Access テーブルの列を OLE オブジェクト型として作成し、
System.Data.SqlClient
名前空間の代わりに Jet 4.0 Provider でSystem.Data.OleDb
名前空間を使用する必要があります。