Visual Basic 6 - Imagens e Banco de dados
O armazenamento de imagens em banco de dados é um tema polêmico e que nos pode levar a escrever um verdadeiro livro se formos nos aprofundar nos diversos tópicos envolvidos no assunto. Por questão de simplicidade e de objetividade iremos abordar o armazenamento de imagens em banco de dados access usando a DAO e depois usando a tecnologia ADO.
Antes de entrar propriamente no assunto, vamos tratar de alguns conceitos básicos relativos ao nosso artigo: como podemos tratar imagens com banco de dados e os controles que usamos para exibir as imagens.
Começando pelo fim - Exibindo imagens BMP, JPEG , GIF , Icones e WMF
Para exibir imagens BMP, JPEG, GIF , Icones e arquivos WMF , podemos usar três controles do VB : PictureBox e Image e Form.
Usando um formulário - Form - a imagem é exibida usando a propriedade Picture do form. O controle Image exige menos recursos do sistema e é mais rápido do que um controle PictureBox , mas possue menos propriedades , métodos e eventos que o controle PictureBox. Para fazer com que a imagem se ajuste ao tamanho do controle Image devemos definir a propriedade Stretch como True ; para fazer com que um controle PictureBox se ajuste ao tamanho da imagem definimos a propriedade AutoSize como True. O controle PictureBox pode ser usado para exibir gráficos e textos impressos via método Print. Abaixo temos o controle PictureBox e Image exibindo imagens:
Para manipular imagens usamos o objeto Picture . Para fazer este serviço geralmente usamos a seguinte sintaxe:
Dim X As
Picture
Set X = LoadPicture("TESTE.BMP")
Set Picture1.Picture = X
Este código cria
uma varíavel do tipo picture , e , carrega a figura TESTE.BMP
usando a função LoadPicture.
A seguir de atribuimos a variável picture a propriedade
Picture nosso controle Picture1.
Podemos também usar um vetor de objetos Picture para manter uma
quantidade de imagens na memória sem usar nenhum controle. Não
podemos criar um objeto Picture com o seguinte código:
Dim
X as New Picture
Para fazer isto devemos usar o objeto StdPicture como mostrado a seguir:
Dim X As New StdPicture
Obs: Podemos capturar uma imagem da area de transferência(O FAMOSO CLIPBOARD) e exibí-la nos controles Picturebox, Image ou Form . No código a seguir usamos o método GetData para copiar uma imagem do clipboard para formulário.(verifique o path do arquivo que quiser carregar.)
|
Para agitar um pouco o assunto vamos criar um visualizador de imagens usando o controle Image. Com o VB isto é barbada , basta juntar alguns controles e um pedaço de código.
1- Criando um visualizador de imagens (para relaxar...)
Nosso projeto terá somente dois formulários: form1 e frmabout e pouco código, vamos lá:
-Inicie um novo projeto no Visual Basic (standard.exe), e crie um projeto com o seguinte jeitão:
Nosso Projeto esta usando os seguintes controles:
Para visualizar uma imagem , selecione o drive no controle DriveListBox e a seguir o diretório de localização da imagem no controle DirListBox. Ela será exibida no controle FileListBox . Basta selecioná-la para exibí-la no controle Image. Obs: Defina a propriedade Stretch do controle Image para True. |
Obs: Perceba que a propriedade do formulário form1, ControlBox foi definida como False e BorderStyle definida como 0-None.
O código para o formulário form1 é o seguinte:
Private Sub Command1_Click() Form1.PrintForm 'imprime o formulário End Sub Private Sub Command2_Click() End 'encerra a aplicação End Sub Private Sub Command3_Click() frmAbout.Show 'exibe formulario c/informacoes sobre o sistema End Sub Private Sub Dir1_Change() File1.Path = Dir1.Path End Sub Private Sub Drive1_Change() On Error GoTo erro Dir1.Path = Drive1.Drive Exit Sub erro: MsgBox "Erro ao acessar o drive !!!", vbDefaultButton1 End Sub Private Sub File1_Click() arquivo_selecionado = File1.Path & "\" & File1.FileName On Error GoTo trataerro Image1.Picture = LoadPicture(arquivo_selecionado) cd1.FileName = selectedfile Exit Sub trataerro: arquivo_selecionado = File1.Path & File1.FileName cd1.FileName = selectedfile On Error GoTo trataerro Image1.Picture = LoadPicture(arquivo_selecionado) End Sub Private Sub mnuExitItem_Click() End End Sub |
Acho que pela simplicidade o código acima dispensa comentários.
O formulário frmabout - tem a seguinte aparência:
Este formulário só traz uma coisa de interessante - o código para exibir as informações do Sistema. Para ver o código do formulário clique no link : Exibindo informações do sistema
As informações são exibidas como na seguinte tela:(mostrei apenas um 'teco' da tela)
Voce pode usar este código e o formulário em seus projetos. Assim mostramos como é simples exibir imagens em projetos VB usando os controles Image e PictureBox
Pegue o código clicando aqui : visual.zip
Exibindo Imagens em banco de dados - DAO - Data Control
Vamos mostrar como exibir imagens armazenadas em um banco de dados. O exemplo que mostrarei , embora muito simples, visa atender o usuário iniciante. Você não precisa guardar a imagem no seu banco de dados , pode apenas armazenar o nome da imagem relacionada , e , salvar a imagem fora do banco de dados no caminho que você referenciou no banco de dados. Este método economiza muito espaço no seu banco de dados e , em muitos casos é o método mais indicado.(Voce sabia que o tamanho de um banco de dados Access esta limitado a 1 Giga - Deve ter aumentando na versão 2000).
Vamos usar um banco de dados Access o qual chamamos imagem.mdb , e uma tabela chamada fotos com a seguinte estrutura:
A tabela possui dois campos:
1-Titulo - que representa o titulo da imagem 2-nomedoarquivo - o nome do arquivo de imagem |
Crie um novo projeto no VB com um formulário como exibido abaixo:
Neste projeto usamos
um formulário com os seguintes controles: 1- Picture Box - Para exibir a imagem 2- Image - Para exibir a imagem ( definimos a propriedade stretch do controle como True) 3- Data Control - que irá fazer a conexão com o banco de dados e irá permitir navegar pelos registros. 4- Label - lbltitulo - Datafield = titulo 5- Label - lblarquivo - Datafield = nomedoarquivo |
Definimos o controle de dados - Data Control - com as seguintes propriedades :
Name = Data1 Connect = Access RecordsetType = Dynaset RecordSource = SELECT * FROM fotos |
O código do projeto é exibido abaixo:
Option Explicit Private Sub Data1_Reposition() Picture1.Picture = LoadPicture(App.Path & "\" & lblarquivo.Caption) Image1.Picture = LoadPicture(App.Path & "\" & lblarquivo.Caption) End Sub Private Sub Form_Load() Data1.DatabaseName = App.Path & "\imagens.mdb" Data1.Refresh End Sub |
Ao executar o projeto teremos o seguinte resultado:
Com apenas algumas linhas criamos um projeto que permite exibir imagens relacionadas em um banco de dados. Naturalmente este é um exemplo muito simples e limitado mas que mostra as possibilidades da ferramenta VB.
Armazenando imagens em um banco de dados
Para armazenar imagens em um banco de dados Access devemos criar uma tabela com um campo do tipo Objeto OLE . Nele podemos armazenar um objeto (como uma planilha do Microsoft Excel, um documento do Microsoft Word, gráficos, sons ou outros dados binários) vinculado ou incorporado a tabela do banco de dados. Em Visual Basic este tipo corresponde dbLongBinary. Como exemplo temos o banco de dados Nwind.mdb (que acompanha o Access 97) e a tabela funcionários que contém a foto armazenada dos funcionários da empresa. O estrutura da tabela funcionários é a seguinte:
Vamos mostrar como exibir imagens armazenadas na tabela funcionários do banco de dados Nwind. (temos aqui uma reprise do código encontrado no artigo - OLE Conceitos )
Crie um novo projeto no Visual Basic , que será a aplicação que controla nosso cadastro de empregados. Temos abaixo (figura 1.0) a tela principal de nossa aplicação em tempo de projeto:
figura 1.0 |
Para montar o formulário acima descrito observe os seguintes passos: 1-Inicie um novo projeto no Visual Basic.Grave o formulário Form1 como Empregados. 2-Adicione ao Form1 os objetos e configure as propriedades conforme a tabela 1.0 abaixo : Tabela 1.0 - Objetos e propriedades do formulário Empregados ---------------------------------------------------------------------------- Objeto Propriedade Configuração ---------------------------------------------------------------------------- Form Name empregados Caption "Automação OLE com Word 7.0" StartUPosition 2-CenterScreen ---------------------------------------------------------------------------- Data Name dtaole Caption "Automação OLE com Word 7.0" Connect Access Databasename "C:\teste\Nwind2000.mdb(*) RecordSetType 1-Dynaset RecordSource "Empregados" ------------------------------------------------------------------ label Name label1(0) Caption "Sobrenome" Autosize True ------------------------------------------------------------------ label Name label1(1) Caption "Nome" Autosize True ------------------------------------------------------------------ label Name label1(2) Caption "Endereço" Autosize True ------------------------------------------------------------------ label Name label1(3) Caption "Cidade" Autosize True ------------------------------------------------------------------ label Name label1(4) Caption "Estado" Autosize True ------------------------------------------------------------------ label Name label1(5) Caption "Cep" Autosize True ------------------------------------------------------------------ TextBox Name text1(0) DataField "sobrenome" DataSource dtaole ------------------------------------------------------------------ TextBox Name text1(1) DataField "Nome" DataSource dtaole ------------------------------------------------------------------ TextBox Name text1(2) DataField "Endereco" DataSource dtaole ------------------------------------------------------------------ TextBox Name text1(3) DataField "cidade" DataSource dtaole ------------------------------------------------------------------ TextBox Name text1(4) DataField "estado" DataSource dtaole ------------------------------------------------------------------ TextBox Name text1(5) DataField "Cep" DataSource dtaole ------------------------------------------------------------------ CommandButton Name command1 Caption "&Sair" ------------------------------------------------------------------ CommandButton Name command2 Caption "&Automação OLE com Word 7.0" ------------------------------------------------------------------ OLE Name Photo Datafield Foto DataSource dtaole SizeMode 0 - Clip ------------------------------------------------------------------ (*)-Esteja certo que o caminho informado aponte para o NWIND2000.MDB. Ao executar o projeto devemos obter a seguinte tela:
Para exibir a imagem usamos um controle OLE e definimos a propriedade DataSource como sendo o Controle de dados utilizado e a propriedade DataField como sendo o nome do campo onde armazenamos as imagens.
A utilização de imagens no formato GIF ou JPG não ocupa tanto espaço e mantém a qualidade da imagem, já as imagens no formato BMP ocupam muito espaço.
OBS: No exemplo acima não poderiamos ter usado um controle picturebox ou image pois as imagens armazenadas no banco de dados Nwind.mdb são imagens objeto OLE e não BMP/ GIF/JPG. Se fizer isto obterá o erro : "Invalid Picture Error When trying to bind Picture control"
Salvando imagens em um banco de dados Access
Há duas técnicas básicas que podemos usar para salvar uma imagem/gráfico em um banco de dados Access via DAO.
A primeira consiste em utilizar um controle PictureBox como um controle vinculado a um campo do banco de dados definido como um Objeto OLE através do tipo de dados dbLongBinary. Isto nos permite carregar e salvar diretamente os dados para o banco de dados através dos comandos LoadPicture e SavePicture, e suporta os formatos BMP , GIF e JPG. O único porém é que os dados são salvos no formato binário e isto dificulta o tratamento da imagem/gráfico fora do ambiente Visual Basic.
A segunda usa um controle Container OLE como um controle vinculado ao campo do banco de dados definido como um objeto OLE através do tipo de dados dbLongBinary. Os dados são armazenados como um Objeto OLE , e isto permite que esteja disponível a qualquer aplicação que suporte a Automação OLE.
Vamos mostrar um exemplo de como usar a primeira técnica. Neste exemplo usaremos o banco de dados Biblio.mdb (Recomendo que você faça uma cópia do arquivo) e a tabela Publishers . Vamos incluir um campo para receber as imagens na tabela pois a estrutura original da tabela Publishers não preve este campo. O campo será incluido via código e definido como do tipo dbLongBinary . A seguir o exemplo passo a passo
Propriedades e controles usados do formulário frmimagem.frm
Objeto Propriedade configuracao Form Name Form1 Caption "Salvando Imagens em um Banco de dados" Data Name Data1 Caption "Banco de dados : Biblio.mdb Tabela: Publishers" Label Name label1 Caption "Editores: " Label Name label2 Caption "" BorderStyle 1 - Fixed Single DataSource Data1 DataField "Name" Image Name picImagem DataSource Data1 DataField "Foto" CommandButton Name Command1 Caption "&Carrega Imagem" CommandButton Name command2 Caption "&Sair" CommonDialog Name cdlImagem Filter "Bitmap files (*.bmp)|*.bmp|JPEG files (*.jpg, *.jpeg)|*.jpg;*.jpeg|GIF Files (*.gif)|*.gif|All Files (*.*)|*.*" DefaultExt "BMP" 'a extensão padrão usada Flags &H1000 'Define que o usuário somente pode informar nomes de arquivos existentes.
A aparência do formulário em tempo de projeto será a seguinte:
O código do projeto segue abaixo :
1-Código da seção General Declarations
Option Explicit Const BIBLIO_PATH = "C:\teste\biblio.mdb" |
Apenas atribuímos a variável BIBLIO_PATH o nome do caminho do nosso banco de dados.
2-Código do evento Form_Load
Private Sub Form_Load() Data1.DatabaseName = BIBLIO_PATH Data1.RecordsetType = 1 'dynaset Data1.RecordSource = "Publishers" Inclui_Campo_Imagem End Sub |
Definimos o nome e o caminho do banco de dados ( BIBLIO_PATH ) , o tipo do Recordset ( usamos um Dynaset ) e o RecordSource (que será a tabela Publishers) e chamamos a procedure Inclui_Campo_Imagem.
3-Código da Procedure Inclui_Campo_Imagem
Private Sub Inclui_Campo_Imagem() Dim dbfTemp As Database, tdfTemp As TableDef, fldTemp As Field Dim Campo_imagem_existe As Boolean On Error GoTo Trata_erro Set dbfTemp = Workspaces(0).OpenDatabase(BIBLIO_PATH) For Each tdfTemp In dbfTemp.TableDefs If tdfTemp.Name = "Publishers" Then For Each fldTemp In tdfTemp.Fields If fldTemp.Name = "Foto" Then Campo_imagem_existe = True Exit For End If Next Exit For End If Next If Campo_imagem_existe = False Then If tdfTemp.Updatable Then Set fldTemp = New Field With fldTemp .Name = "Foto" .Type = dbLongBinary End With tdfTemp.Fields.Append fldTemp Else MsgBox "O seu Banco de dados não suporta esta operação ! ", vbExclamation End If End If On Error GoTo 0 Exit Sub Trata_erro: MsgBox Err.Description, vbExclamation End End Sub |
Esta procedure irá abrir o banco de dados e verificar se o existe o campo Foto . Se não existir o campo será criado.
4-Código do botão de comando Carrega Imagem :
Private Sub Command1_Click() On Error GoTo Cancela_carga cdlimagem.ShowOpen On Error GoTo erro_na_carga picimagem = LoadPicture(cdlimagem.FileName) On Error GoTo 0 On Error GoTo 0 Exit Sub Cancela_carga: If Err.Number <> cdlCancel Then MsgBox Err.Description, vbExclamation Else Exit Sub End If erro_na_carga: MsgBox Err.Description, vbExclamation Exit Sub End Sub |
Ao clicar no botão a caixa de diálogo se abre para que o usuário informe a imagem que deseja carregar no arquivo. Após a seleção a imagem é gravada na base de dados.
Salvando imagens em um banco de dados com ADO
Aposto que você estava aguardando este tópico , vamos mostrar como salvar imagens em um banco de dados usando ADO.Usaremos algumas funções em um módulo para poder armazenar a imagem no banco de dados. Geralmente esta não é a solução adotada pois dependendo da quantidade e do formato das imagens o banco de dados ficará muito grande.
Vamos ao projeto:
1-Inicie um novo projeto no VB:
2-Nosso formulário terá a seguinte aparência: ( O projeto terá um único formulário: frmimagem )
Controles usados no
projeto: 1- Controle PictureBox - picimagem - Para exibir a imagem 2- Controle CommandButton - Diversas tarefas 3- Controle CommonDialog - Para abrir a caixa de seleção de arquivos 4- Um textBox - Para exibir a descrição da imagem (Não esqueça de referenciar a ADO 2.5 no seu projeto.) Obs: No meu caso eu estou usando o Access 2000 por isso o provedor terá que ser o JET 4.0 |
3-) Insira um módulo no projeto e chame-o de imagem.bas. Ele conterá as procedures que irão gravar e exibir as imagens armazenadas no banco de dados. Vejamos o código do módulo imagem.bas:
General Declarations
Option Explicit Private Const nBUFFER As Long = 1024 |
Procedure SalvaImagem: Os parâmetros são: o campo onde deseja salvar a imagem e o nome da imagem.
Public Sub SalvaImagem(f As ADODB.Field, File As String) Dim b() As Byte Dim ff As Long Dim n As Long On Error GoTo ErrHandler ff = FreeFile Open File For Binary Access Read As ff n = LOF(ff) If n Then ReDim b(1 To n) As Byte Get ff, , b() End If Close ff f.Value = b() Exit Sub ErrHandler: MsgBox "ERROR: " & Err.Description End Sub |
Função RecuperaImagem: O parâmetro é o campo de onde deseja recuperar a imagem.
Public Function RecuperaImagem(f As ADODB.Field) As StdPicture Dim b() As Byte Dim ff As Long Dim File As String On Error GoTo ErrHandler Call GetRandomFileName(File) ff = FreeFile Open File For Binary Access Write As ff b() = f.Value Put ff, , b() Close ff Erase b Set GetImageFromField = LoadPicture(File) Kill File Exit Function ErrHandler: MsgBox "ERROR: " & Err.Description End Function 'imagens grandes Public Sub SalvaImagensGrandes(f As ADODB.Field, File As String) Dim b() As Byte Dim ff As Long Dim i As Long Dim FileLen As Long Dim Blocks As Long Dim LeftOver As Long On Error GoTo ErrHandler ff = FreeFile Open File For Binary Access Read As ff FileLen = LOF(ff) Blocks = Int(FileLen / nBUFFER) LeftOver = FileLen Mod nBUFFER ReDim b(LeftOver) Get ff, , b() f.AppendChunk b() ReDim b(nBUFFER) For i = 1 To Blocks Get ff, , b() f.AppendChunk b() Next Close ff Exit Sub ErrHandler: MsgBox "ERROR: " & Err.Description End Sub |
Função ExibImagensGrandes: O parâmetro é o campo do qual queremos recuperar a imagem.
Public Function ExibeImagensGrandes(f As ADODB.Field) As StdPicture Dim b() As Byte Dim ff As Long Dim File As String Dim i As Long Dim FileLen As Long Dim Blocks As Long Dim LeftOver As Long On Error GoTo ErrHandler File = "temppic.bmp" ff = FreeFile Open File For Binary Access Write As ff Blocks = Int(f.ActualSize / nBUFFER) LeftOver = f.ActualSize Mod nBUFFER b() = f.GetChunk(LeftOver) Put ff, , b() For i = 1 To Blocks b() = f.GetChunk(nBUFFER) Put ff, , b() Next Close ff Erase b Set ExibeImagensGrandes = LoadPicture(File) Kill File Exit Function ErrHandler: MsgBox "ERROR: " & Err.Description End Function |
Função SalvaImagensGrandes: Os parâmetros são : o campo onde deseja salvar a imagem e o nome da imagem.
Public Sub SalvaImagensGrandes(f As ADODB.Field, File As String) Dim b() As Byte Dim ff As Long Dim i As Long Dim FileLen As Long Dim Blocks As Long Dim LeftOver As Long On Error GoTo ErrHandler ff = FreeFile Open File For Binary Access Read As ff FileLen = LOF(ff) Blocks = Int(FileLen / nBUFFER) LeftOver = FileLen Mod nBUFFER ReDim b(LeftOver) Get ff, , b() f.AppendChunk b() ReDim b(nBUFFER) For i = 1 To Blocks Get ff, , b() f.AppendChunk b() Next Close ff Exit Sub ErrHandler: MsgBox "ERROR: " & Err.Description End Sub |
4-) Ao executar o programa teremos a seguinte tela:
5-) Ao usar os botões de comandos para se movimentar as imagens serão exibidas, e, ao clicar no botão para inserir um novo registro com uma nova imagem a seguinte tela será exibida:
Vou mostrar somente o código da carga do formulário , da exibição das imagens e da gravação das mesmas.
- Código do evento Form_Load
Private Sub Form_Load() 'abre conexao e define o recordset cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\teste\imagens.mdb;" rs.CursorLocation = adUseClient rs.Open "Select * From Fotos", cnn, adOpenKeyset, adLockOptimistic, adCmdText If rs.RecordCount = 0 Then ActiveControles False, "cmdinclui" End If exibe_registros End Sub |
- Código da procedure exibe_registros
Private Sub exibe_registros() Set Me.picimagem = ExibeImagensGrandes(rs.Fields("Foto")) txtdescricao = rs.Fields("descricao") End Sub |
- Código do evento click do botão cmdgravar
Private Sub cmdgravar_Click() On Error GoTo ErrHandler If fotos = "" Then fotos = App.Path + "\imagem.gif" End If 'inclui um registro rs.AddNew If txtdescricao.Text = "" Then txtdescricao.Text = "Nada a declarar" End If rs("Descricao") = txtdescricao.Text Call SalvaImagem(rs.Fields("Foto"), fotos) rs.Update ActiveControles True rs.MoveLast cmdgravar.Visible = False Exit Sub ErrHandler: MsgBox "ERROR: " & Err.Description End Sub |
Fique a vontade para melhorar o projeto , eu só queria mostrar como salvar e recuperar imagens de um banco de dados via ADO. Antes que você mude de 'canal' pegue o código completo clicando aqui : img_bd.zip
Adios ! e, até o próximo artigo... ;-)
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: