Visual C をシャープにして、データベースから PictureBox コントロールに画像を直接コピーする
この記事では、ファイルにイメージを保存することなく、データベースに格納されているイメージを Windows フォームの PictureBox コントロールに直接コピーする方法について説明します。
元の製品バージョン: Visual C#
元の KB 番号: 317701
概要
この詳細な記事では、イメージをファイルに保存することなく、データベースに格納されているイメージを Windows フォームの PictureBox コントロールに直接コピーする方法について説明します。
Visual Basic 6.0 では、バイナリ ラージ オブジェクト {BLOB) データをファイルに保存する中間手順なしで、PictureBox コントロール内のデータベースから画像を表示する唯一の方法は、PictureBox を ActiveX Data Objects (ADO) データ コントロールや Recordset などのデータ ソースにバインドすることです。 LoadPicture ステートメントで使用するためにイメージをファイルに保存せずに、プログラムによって BLOB をコントロールに読み込む方法 (データ バインドなし) はありません。
この記事では、基本クラスの オブジェクトをMemoryStream
System.IO
使用して、データベースから 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 つのボタン コントロールを追加します。 の
Button1
プロパティをText
[ファイル] を [データベース] に、プロパティButton2
をText
[データベース] から [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";
のイベント プロシージャ (File to Database) に
Click
次のButton1
コードを挿入します。 必要に応じて、使用可能なサンプル イメージ ファイルへのファイル パスを調整します。 このコードは、ディスクから (オブジェクトを使用して) イメージ ファイルを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); }
のイベント プロシージャ (Database to PictureBox) に
Click
次のButton2
コードを挿入します。 このコードは、データベース内のテーブルから 行をBLOBTest
に取得し、最後にDataSet
追加したイメージをByte
配列にコピーしてからオブジェクトにMemoryStream
コピーし、 をMemoryStream
PictureBox コントロールの プロパティに読み込Image
みます。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 つのサンプル イメージをデータベースに読み込みます。
[ データベースから 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); }
プロジェクトを実行します。 [ データベースから PictureBox] ボタンを クリックして、以前に保存した画像を PictureBox コントロールに表示します。 新しく追加したボタンをクリックして、PictureBox からデータベースに画像を保存します。 次に、もう一度 [ Database to PictureBox ] ボタンをクリックして、イメージが正しく保存されたことを確認します。
落とし穴
このテストは、Access とSQL Serverで配布されたサンプル Northwind データベースの Employees テーブルの [写真] 列では機能しません。 [写真] 列に格納されているビットマップ イメージは、Visual Basic 6.0 OLE Container コントロールによって作成されたヘッダー情報でラップされます。
Access データベースを使用してこのコードをテストする必要がある場合は、Access テーブルの列を OLE オブジェクト型として作成し、名前空間の代わりに Jet 4.0 Provider で名前空間を使用
System.Data.OleDb
するSystem.Data.SqlClient
必要があります。