Condividi tramite


Copiare un'immagine da un database direttamente in un controllo PictureBox con Visual C sharp

Questo articolo descrive come copiare un'immagine archiviata in un database direttamente in un controllo PictureBox in un Windows Form senza dover salvare l'immagine in un file.

Versione originale del prodotto: Visual C#
Numero KB originale: 317701

Riepilogo

Questo articolo dettagliato descrive come copiare un'immagine archiviata in un database direttamente in un controllo PictureBox in un Windows Form senza dover salvare l'immagine in un file.

In Visual Basic 6.0, l'unico modo per visualizzare un'immagine da un database in un controllo PictureBox, senza il passaggio intermedio di salvataggio dei dati blob (Binary Large Object) in un file, consiste nell'associare PictureBox a un'origine dati, ad esempio un controllo dati ADO (ActiveX Data Objects) o un oggetto Recordset. Non esiste alcun modo (senza data binding) per caricare un BLOB a livello di codice in un controllo senza salvare l'immagine in un file da usare dall'istruzione LoadPicture.

In questo articolo si userà l'oggetto MemoryStream della System.IO classe di base per copiare i dati dell'immagine dal database direttamente nel controllo PictureBox.

Requisiti

L'elenco seguente illustra i Service Pack consigliati per hardware, software, infrastruttura di rete e Service Pack necessari:

  • Visual Studio .NET installato in un sistema operativo Windows compatibile
  • Un'istanza disponibile di SQL Server o un database di Access disponibile per il test

Questo articolo presuppone che l'utente abbia familiarità con gli argomenti seguenti:

  • Applicazioni visual C# .NET Windows Form
  • Archiviazione BLOB (Binary Large Object) nei database
  • ADO.NET l'accesso ai dati

Esempio

  1. Creare una tabella di SQL Server o Access con la struttura seguente:

    CREATE TABLE BLOBTest
    (
        BLOBID INT IDENTITY NOT NULL,
        BLOBData IMAGE NOT NULL
    )
    
  2. Aprire Visual Studio .NET e creare un nuovo progetto di applicazione Windows Visual C#.

  3. Aggiungere un controllo PictureBox e due controlli Button all'impostazione predefinita Form1 dalla casella degli strumenti. Impostare la Text proprietà di Button1 su File su Database e la Text proprietà di Button2 su Database su PictureBox.

  4. Inserire le istruzioni using seguenti nella parte superiore del modulo di codice del modulo:

    using System.Data.SqlClient;
    using System.IO;
    using System.Drawing.Imaging;
    
  5. Aggiungere la dichiarazione seguente per il database stringa di connessione solo all'interno della classe pubblica Form1: System.Windows.Forms.Form class dichiarazione e modificare il stringa di connessione in base alle esigenze:

    String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
    
  6. Inserire il codice seguente nella Click routine evento di Button1 (Da file a database). Modificare il percorso del file in un file di immagine di esempio disponibile in base alle esigenze. Questo codice legge il file di immagine dal disco (usando un FileStream oggetto ) in una Byte matrice e quindi inserisce i dati nel database usando un oggetto Command con parametri.

    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. Inserire il codice seguente nella Click routine evento di Button2 (Database a PictureBox). Questo codice recupera le righe dalla BLOBTest tabella nel database in un DataSetoggetto , copia l'immagine aggiunta più di recente in una Byte matrice e quindi in un MemoryStream oggetto e quindi carica nella MemoryStream Image proprietà del controllo PictureBox.

    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. Premere F5 per compilare ed eseguire il progetto.

  9. Fare clic sul pulsante File su database per caricare almeno un'immagine di esempio nel database.

  10. Fare clic sul pulsante Database to PictureBox per visualizzare l'immagine salvata nel controllo PictureBox.

  11. Se si desidera poter inserire l'immagine dal controllo PictureBox direttamente nel database, aggiungere un terzo controllo Button e inserire il codice seguente nella relativa Click routine evento. Questo codice recupera i dati dell'immagine dal controllo PictureBox in un MemoryStream oggetto , copia in MemoryStream una Byte matrice e quindi salva la Byte matrice nel database usando un oggetto Command con parametri.

    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. Eseguire il progetto. Fare clic sul pulsante Database to PictureBox per visualizzare un'immagine salvata in precedenza nel controllo PictureBox. Fare clic sul pulsante appena aggiunto per salvare l'immagine da PictureBox nel database. Fare quindi di nuovo clic sul pulsante Database to PictureBox per confermare che l'immagine è stata salvata correttamente.

Insidie

  • Questo test non funzionerà con la colonna Photo nella tabella Employees del database Northwind di esempio distribuito con Access e SQL Server. Le immagini bitmap archiviate nella colonna Photo vengono incapsulate con le informazioni di intestazione create dal controllo Contenitore OLE di Visual Basic 6.0.

  • Se è necessario usare un database di Access per testare questo codice, sarà necessario creare la colonna nella tabella di Access come tipo OGGETTO OLE e usare lo System.Data.OleDb spazio dei nomi con il provider Jet 4.0 al posto dello spazio dei System.Data.SqlClient nomi.