VB.NET - Exibindo imagens armazenadas em um Banco
de dados
Neste artigo vamos exibir imagens armazenadas em uma base de dados Access em um formulários Windows .
Para você entender melhor o projeto que vou criar você deve ler o artigo : Desvendando os segredos do Data Binding no VB.NET - I
Pois vou usar a vinculação de dados no formulário.
Abaixo temos a exibição da tabela Categories do banco de dados Northwind.mdb (um velho conhecido nosso...). Na coluna Picture da tabela temos armazenadas as imagens de cada categoria.
Nosso objetivo será criar um projeto que exiba os dados da tabela em controles de forma que conforme o usuário navegue pelos registros os dados sejam dinamicamente mostrados juntamente com cada imagem da categoria correspondente.
![]() |
Inicie então um novo projeto no VS.NET do tipo Windows Application usando a linguagem VB.NET e no formulário padrão insira os controles : label , textbox , Button e PictureBox conforme o layout abaixo.
![]() |
Defina os imports usado pelo sistema conforme abaixo :
Imports
System.IOImports
System.DataImports
System.ConfigurationImports
System.Data.OleDb
Defina também as variáveis abaixo no início do formulário , pois serão usadas no projeto:
Private MSACCESSIMAGEMOFFSET As Integer = 78
Private ds As DataSet
Private da As OleDbDataAdapter
Private bm As BindingManagerBase
Em
seguida vamos criar um arquivo de configuração para aplicação onde iremos
armazenar as strings de conexão para o banco de dados SQL Server e para o banco
de dados Access.
Abaixo o código do nosso arquivo de configuração:(Nele estou armazenando a string de conexão com o SQL Server e o nome do banco de dados Access usado no projeto.)
Para esta
aplicação o arquivo de configuração tem o seguinte conteúdo:
|
Nota: Para saber mais sobre como criar o seu arquivo de configuração leia o artigo : NET - Tratando arquivos de configuração
Agora vamos ao código:
No evento Load do formulário inclua o código abaixo. Ele é responsável por :
Private Sub frmFoto_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' cria um DataSet ds = New DataSet ' cria um DataAdapter e retorna a tabela Categories Dim selectCommand As String = "SELECT CategoryID, CategoryName, Description FROM Categories" da = New OleDbDataAdapter(selectCommand, ConfigurationSettings.AppSettings("AcessoBD")) da.FillSchema(ds, SchemaType.Source, "Categories") da.Fill(ds, "Categories") ' vincula a tabela aos controles txtCodigo.DataBindings.Add("Text", ds, "Categories.CategoryID") txtNome.DataBindings.Add("Text", ds, "Categories.CategoryName") txtDescricao.DataBindings.Add("Text", ds, "Categories.Description") ' obtem o bm para a tabela pai bm = BindingContext(ds, "Categories") ' atualiza a imagem em resposta a cada posição do registro AddHandler bm.PositionChanged, AddressOf bm_PositionChanged ' atualiza e exibe para o primeiro registro bm_PositionChanged(Nothing, Nothing) End Sub |
Para que possamos controlar a exibição dos dados conforme a navegação do usuário pelos registros incluir o código abaixo no evento PostionChanged do BindingManager. Ele irá selecionar a imagem referente a posição atual do registro e irá carregar e exibir a imagem no controle PictureBox.
Private Sub bm_PositionChanged(ByVal sender As [Object], ByVal e As EventArgs) ' refresca a foto exibida quando o registro atual muda ' obtem uma nova CategoryID usando o BindingManager Dim categoryId As Integer = CInt(ds.Tables("Categories").Rows(bm.Position)("CategoryID")) ' cria a conexao Dim conn As New OleDbConnection(ConfigurationSettings.AppSettings("acessoBD")) ' cria o commando para retornar a categoria das fotos Dim sqlText As [String] = "SELECT Picture FROM Categories WHERE CategoryID=" & categoryId Dim cmd As New OleDbCommand(sqlText, conn) ' retorna a foto do banco de dados conn.Open() Dim image As [Byte]() = CType(cmd.ExecuteScalar(), [Byte]()) ' escreve o stream removendo a imagem do cabecalho Dim ms As New MemoryStream ms.Write(image, MSACCESSIMAGEMOFFSET, image.Length - MSACCESSIMAGEMOFFSET) conn.Close() ' carrega a imagem no picturebox picFoto.Image = System.Drawing.Image.FromStream(ms) ms.Close() End Sub |
O Microsoft Access armazena as imagens no banco de dados com um objeto OLE que encapsula a imagem atual. Desta forma que a imagem possui um header com um tamanho variável que precisa ser extraído para obter a imagem. O tamanho deste header para imagens do tipo bitmap armazenadas no Northwind.mdb é de 78 bytes.
A imagem armazenada é retornada para um (array de bytes)Byte array. O byte array é copiado no objeto MemoryStream usando uma sobrecarga do método Write() que permite que 78 bytes sejam definidos.
O método estático FromStream da classe Image cria um objeto Image a partir de MemoryStream que é carregado no PictureBox.
Finalmente o código relativo a cada botão de movimentação do formulário para permitir a navegação pelos registros.
Private Sub btnPrimeiro_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrimeiro.Click bm.Position = 0 End Sub Private Sub btnAnterior_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnterior.Click bm.Position = bm.Position - 1 End Sub Private Sub btnProximo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProximo.Click bm.Position = bm.Position + 1 End Sub Private Sub btnUltimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUltimo.Click bm.Position = bm.Count - 1 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub |
Abaixo o resultado da execução do projeto:
Notou como é simples criar um projeto com acesso a dados e fazer o tratamento dos mesmos usando o novo databinding do VB.NET ?
Pegue o código completo do projeto aqui : fotoDB.zip
Eu sei é apenas VB.NET , mas eu gosto...
José Carlos Macoratti