英語で読む

次の方法で共有


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

サンプル

  1. 次の構造の SQL Server または Access テーブルを作成します。

    CREATE TABLE BLOBTest
    (
        BLOBID INT IDENTITY NOT NULL,
        BLOBData IMAGE NOT NULL
    )
    
  2. Visual Studio .NET を開き、新しい Visual C# Windows アプリケーション プロジェクトを作成します。

  3. ツールボックスから既定の Form1 に PictureBox コントロールと 2 つの Button コントロールを追加します。 Button1Text プロパティを File から Database に設定しButton2Text プロパティを Database を PictureBox に設定

  4. フォームのコード モジュールの先頭に次の using ステートメントを挿入します。

    using System.Data.SqlClient;
    using System.IO;
    using System.Drawing.Imaging;
    
  5. パブリック クラス Form1 内のデータベース 接続文字列に次の宣言を追加します。宣言をSystem.Windows.Forms.Form classし、必要に応じて接続文字列を調整します。

    String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
    
  6. Button1Click イベント プロシージャに次のコードを挿入します (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);
    }
    
  7. Button2Click イベント プロシージャに次のコードを挿入します (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);
    }
    
  8. F5 キーを押して、プロジェクトをコンパイルし、実行します。

  9. [データベースへのファイル] ボタンをクリックして、少なくとも 1 つのサンプル イメージをデータベースに読み込みます。

  10. [ Database to PictureBox ] ボタンをクリックして、保存した画像を PictureBox コントロールに表示します。

  11. PictureBox コントロールから直接データベースに画像を挿入できるようにする場合は、3 つ目の Button コントロールを追加し、その Click イベント プロシージャに次のコードを挿入します。 このコードは、PictureBox コントロールから画像データを MemoryStream オブジェクトに取得し、 MemoryStreamByte 配列にコピーした後、パラメーター化された 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);
    }
    
  12. プロジェクトを実行します。 [ 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名前空間を使用する必要があります。