WPF - Salvando e recuperando imagens do SQL Server (C#)


Neste tutorial vou mostrar como podemos salvar e recuperar imagens de um banco de dados SQL Server em uma aplicação WPF usando a linguagem C#.

1- Criando o projeto WPF

Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo WPF Application com o nome TratandoImagens_WPF;

Vamos criar um banco de dados chamado Cadastro.mdf e uma tabela Fotos com a seguinte estrutura:

A tabela possui um campo id chave primária do tipo identity e um campo imagem do tipo Image e um campo nome do tipo nvarchar().

Vamos selecionar o arquivo MainWindow.xaml e a partir da ToolBox vamos incluir nesta janela os controles:

Conforme o leiaute abaixo:

A formatação da cor de fundo da janela fica a seu critério.

O código XAML gerado é visto abaixo:

<Window x:Class="TratandoImagens_WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Inclui Imagens" Height="398" Width="525">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Black" Offset="0" />
                <GradientStop Color="#101E3B74" Offset="1" />
                <GradientStop Color="#DBE8C795" Offset="0.5" />
            </LinearGradientBrush>
        </Grid.Background>
        <Image Height="246" HorizontalAlignment="Left" Margin="73,60,0,0" Name="imgArquivo" Stretch="Fill" VerticalAlignment="Top" Width="378" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="73,31,0,0" Name="txtNome" VerticalAlignment="Top" Width="341" />
        <Button Content="Salvar" Height="35" HorizontalAlignment="Left" Margin="268,312,0,0" Name="btnSalvar" VerticalAlignment="Top" Width="75" Click="btnSalvar_Click" />
        <Button Content="Próximo" Height="35" HorizontalAlignment="Left" Margin="352,312,0,0" Name="btnProximo" VerticalAlignment="Top" Width="75" Click="btnProximo_Click" />
        <Button Content="..." Height="23" HorizontalAlignment="Left" Margin="415,31,0,0" Name="btnProcurar" VerticalAlignment="Top" Width="36" Click="btnProcurar_Click" />
    </Grid>
</Window>

No evento Click do botão Procurar vamos incluir o código abaixo para selecionar um arquivo Imagem:

  private void btnProcurar_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.ShowDialog();

            try
            {
                fs = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read);
                dadosImagem = new byte[fs.Length];
                fs.Read(dadosImagem, 0, System.Convert.ToInt32(fs.Length));
                fs.Close();

                ImageSourceConverter imgs = new ImageSourceConverter();
                imgArquivo.SetValue(Image.SourceProperty, imgs.ConvertFromString(dlg.FileName.ToString()));

                txtNome.Text = dlg.FileName.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro :: " + ex.Message);
            }
        }

Executando o projeto e selecionando uma imagem teremos:

Para salvar a imagem basta clicar no botão Salvar cujo código é colocado no evento Click do controle Button conforme abaixo:

  private void btnSalvar_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                sqlCon = new SqlConnection(conStr);
                sqlCon.Open();
                string sqlCmd = "INSERT INTO Fotos(imagem,nome) values(@imagem,@nome)";
                SqlCommand sc = new SqlCommand(sqlCmd, sqlCon);
                sc.Parameters.AddWithValue("@imagem", dadosImagem);
                sc.Parameters.AddWithValue("@nome", txtNome.Text);
                sc.ExecuteNonQuery();
                sc.Dispose();
                sqlCon.Close();
                MessageBox.Show("Imagem Salva ");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro :: " + ex.Message);
            }
        }

O código é bem simples :

1- Abrimos uma conexão com o banco de dados Cadastro usando a string de conexão definida;
2- Criamos um objeto Command que usa a instrução SQL para incluir registros : "INSERT INTO Fotos(imagem,nome) values(@imagem,@nome)";
3- Passamos os parâmetros que são : a imagem escolhida e e seu nome;
4- Executamos  o comando na conexão :  sc.ExecuteNonQuery();

E pronto. A imagem será salva no banco de dados.

No evento Click do botão Próximo iremos chamar uma nova janela para exibir as imagens salvas. O seu código é dado a seguir:

private void btnProximo_Click(object sender, RoutedEventArgs e)

{

   Window1 oWin = new Window1();

   oWin.Show();

   this.Close();

}

 

Recuperando imagens salvas

Nosso próximo objetivo será recuperar as imagens salvas e exibi-las em uma nova janela da aplicação WPF.

Vamos incluir uma nova janela no projeto. No menu Project clique em Add Window e aceite o nome padrão Window1.xaml;

Selecione a janela Window1.xaml e inclua a partir da ToolBox os seguintes controles:

Conforme o leiaute abaixo:

O código xaml gerado é o seguinte:

<Window x:Class="TratandoImagens_WPF.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Visualizar Imagens" Height="482" Width="669">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                <GradientStop Color="Black" Offset="0" />
                <GradientStop Color="White" Offset="1" />
                <GradientStop Color="#FFE9EFFC" Offset="0.5" />
                <GradientStop Color="#FF71D871" Offset="0.25" />
            </LinearGradientBrush>
        </Grid.Background>
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="27,47,0,0" Name="txtbImagens" Text="Imagens Disponíveis" VerticalAlignment="Top" Width="174" 
Background="#C3FCEB17" FontSize="15" FontStretch="Normal" FontWeight="Medium" />
        <ListBox Height="315" HorizontalAlignment="Left" Margin="27,76,0,0" Name="lstImagens" VerticalAlignment="Top" Width="174" Background="#80FEEFE4" />
        <Image Height="344" HorizontalAlignment="Left" Margin="211,47,0,0" Name="imgImagem" Stretch="Fill" VerticalAlignment="Top" Width="416" />
        <Button Content="Encerrar" Height="23" HorizontalAlignment="Left" Margin="552,399,0,0" Name="btnSair" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>

Vamos definir o código da janela Window1.xaml.

Os namespaces usados na janela são:

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media.Imaging;

using System.IO;

using System.Data.SqlClient;

using System.Data;

Vamos definir no início da janela as variáveis que serão visíveis por todo o código usado na janela:

DataSet ds = null;

SqlConnection sqlCon = null;

string conStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=True;";

Agora no evento Loaded da janela vamos incluir o código abaixo:

private void Window_Loaded(object sender, RoutedEventArgs e)

{

 sqlCon = new SqlConnection(conStr);

 sqlCon.Open();

 ds = new DataSet();


 SqlDataAdapter
sqa = new SqlDataAdapter("SELECT nome FROM Fotos", sqlCon);

 sqa.Fill(ds);

 sqlCon.Close();

 foreach (DataRow dataRow in ds.Tables[0].Rows)

 {

   ListBoxItem lbItem = new ListBoxItem();

   lbItem.Content = dataRow[0].ToString();

   lstImagens.Items.Add(lbItem);

 }

}

Este código abra uma conexão usando a string de conexão definida e obtém o nome das fotos armazenadas no banco de dados exibindo-as no controle ListBox - lstImagens;

Quando o botão Próximo da janela MainWindow.xaml form clicado a janela Window1.xaml será aberta e exibirá as imagens gravadas:

Selecionando uma imagem do controle ListBox a mesma será exibida no controle PictureBox da janela Window1.xaml:

Para isso devemos incluir o código abaixo no evento SelectionChanged do controle ListBox.

   private void lstImagens_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SqlConnection sqlCon = new SqlConnection(conStr);
            ListBoxItem lb = (lstImagens.SelectedItem as ListBoxItem);
            sqlCon.Open();
            ds = new DataSet();
         
            SqlDataAdapter sqa = new SqlDataAdapter ("Select imagem from Fotos where nome='" + lb.Content.ToString() + "'", sqlCon);
            sqa.Fill(ds);
            sqlCon.Close();
            byte[] data = (byte[]) ds.Tables[0].Rows[0][0];
            MemoryStream strm = new MemoryStream();
            strm.Write(data, 0, data.Length);
            strm.Position = 0;
            System.Drawing.Image img = System.Drawing.Image.FromStream(strm);
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            MemoryStream ms = new MemoryStream();
            img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);
            bi.StreamSource = ms;
            bi.EndInit();
            imgArquivo.Source = bi;
        }

Com isso mostrei como salvar e recuperar imagens em um banco de dados SQL Server usando a linguagem C# em uma aplicação WPF>

Pegue o projeto completo aqui: TratandoImagens_WPF.zip

1Pedro 5:6 Humilhai-vos, pois, debaixo da potente mão de Deus, para que a seu tempo vos exalte;
1Pedro 5:7
lançando sobre ele toda a vossa ansiedade, porque ele tem cuidado de vós.

Referências:


José Carlos Macoratti