Copiar uma imagem de um banco de dados diretamente para um controle PictureBox com Visual C afiado

Este artigo descreve como copiar uma imagem armazenada em um banco de dados diretamente em um controle PictureBox em um Formulário do Windows sem a necessidade de salvar a imagem em um arquivo.

Versão original do produto: Visual C#
Número de KB original: 317701

Resumo

Este artigo passo a passo descreve como copiar uma imagem armazenada em um banco de dados diretamente em um controle PictureBox em um Formulário windows sem a necessidade de salvar a imagem em um arquivo.

No Visual Basic 6.0, a única maneira de exibir uma imagem de um banco de dados em um controle PictureBox, sem a etapa intermediária de salvar os dados binários de objeto grande {BLOB) em um arquivo, é associar a PictureBox a uma fonte de dados, como um ADO (ActiveX Data Objects) Controle de Dados ou Recordset. Não há como (sem associação de dados) carregar programaticamente um BLOB em um controle sem salvar a imagem em um arquivo para uso pela instrução LoadPicture.

Neste artigo, usaremos o MemoryStream objeto da System.IO classe base para copiar os dados de imagem do banco de dados diretamente no controle PictureBox.

Requisitos

A lista a seguir descreve o hardware, o software, a infraestrutura de rede e os pacotes de serviço recomendados que você precisará:

  • Visual Studio .NET instalado em um sistema operacional Windows compatível
  • Uma instância disponível de SQL Server ou um banco de dados de acesso disponível para teste

Este artigo pressupõe que você esteja familiarizado com os seguintes tópicos:

  • Aplicativos de Windows Forms .NET do Visual C#
  • Armazenamento de blob (objeto grande binário) em bancos de dados
  • ADO.NET acesso a dados

Amostra

  1. Crie uma tabela de SQL Server ou Access com a seguinte estrutura:

    CREATE TABLE BLOBTest
    (
        BLOBID INT IDENTITY NOT NULL,
        BLOBData IMAGE NOT NULL
    )
    
  2. Abra o Visual Studio .NET e crie um novo Projeto de Aplicativo windows do Visual C#.

  3. Adicione um PictureBox e dois controles button ao Formulário1 padrão da caixa de ferramentas. Defina a Text propriedade de Button1como Arquivo para Banco de Dados e a Text propriedade de como Banco de Button2Dados como PictureBox.

  4. Insira o seguinte usando instruções na parte superior do módulo de código do formulário:

    using System.Data.SqlClient;
    using System.IO;
    using System.Drawing.Imaging;
    
  5. Adicione a seguinte declaração para o banco de dados cadeia de conexão apenas dentro da classe pública Form1: System.Windows.Forms.Form class declaração e ajuste o cadeia de conexão conforme necessário:

    String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
    
  6. Insira o código a Click seguir no procedimento de evento de (Arquivo para Banco deButton1 Dados). Ajuste o caminho do arquivo para um arquivo de imagem de exemplo disponível conforme necessário. Esse código lê o arquivo de imagem do disco (usando um FileStream objeto) em uma Byte matriz e insere os dados no banco de dados usando um objeto Command parametrizado.

    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. Insira o código a Click seguir no procedimento de evento de (Banco de Button2Dados para PictureBox). Esse código recupera as linhas da BLOBTest tabela no banco de dados em um DataSet, copia a imagem adicionada mais recentemente em uma Byte matriz e, em seguida, em um MemoryStream objeto e carrega a MemoryStreamImage na propriedade do controle 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. Pressione F5 para compilar e executar o projeto.

  9. Clique no botão Arquivo no Banco de Dados para carregar pelo menos uma imagem de exemplo no banco de dados.

  10. Clique no botão Banco de Dados para PictureBox para exibir a imagem salva no controle PictureBox.

  11. Se você quiser ser capaz de inserir a imagem do controle PictureBox diretamente no banco de dados, adicione um terceiro controle button e insira o código a seguir em seu Click procedimento de evento. Esse código recupera os dados de imagem do controle PictureBox em um MemoryStream objeto, copia o MemoryStream em uma Byte matriz e salva a Byte matriz no banco de dados usando um objeto Command parametrizado.

    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. Execute o projeto. Clique no botão Banco de Dados para PictureBox para exibir uma imagem salva anteriormente no controle PictureBox. Clique no botão recém-adicionado para salvar a imagem da PictureBox no banco de dados. Em seguida, clique no botão Banco de Dados para PictureBox novamente para confirmar se a imagem foi salva corretamente.

Armadilhas

  • Este teste não funcionará com a coluna Foto na tabela Funcionários do banco de dados northwind de exemplo distribuído com Access e SQL Server. As imagens de bitmap armazenadas na coluna Foto são encapsuladas com as informações de cabeçalho criadas pelo controle contêiner OLE do Visual Basic 6.0.

  • Se você precisar usar um banco de dados access para testar esse código, precisará criar a coluna na tabela Access como tipo Objeto OLE e usar o System.Data.OleDb namespace com o Provedor Jet 4.0 no lugar do System.Data.SqlClient namespace.