Fórum Gravar Imagem no Firebird: Algumas Opções!! #289260
23/07/2005
0
Sei que já tem vários tópicos sobre isso aqui no fórum, e eu dei uma olhada em alguns, mas estou precisando de algumas considerações específicar, se for possível. Estou usando Delphi 7 + Firebird 1.5 = dbExpress. Vou numerar pra ficar melhor:
[b:9b7f98727f]1. Gravar efetivamente a imagem no BD: [/b:9b7f98727f]Bom, aqui eu gostaria de saber como gravar mesmo a imagem no banco de dados. Já tenho o campo BLOB type 2 na tabela. Eu usava antes o sistema de gravar o caminho da imagem no banco. E fiz toda estrutura pra gravar a imagem e exibir ela, agora estou mudando.
Então a idéia é, quando clicar num botão, ele executar um OpenPictureDialog e quando eu selecionar o arquivo, ele salvar a imagem no banco.
Eu tentei usar o seguinte comando, que achei aqui no fórum:
(qryCadastro.FieldByName(´arq_blob´) as TBlobField).LoadFromFile (OpenPictureDialog.FileName);
Mas quando eu tento executar ele dá um problema no TBlobField e no LoadFromFile, dizendo que não sao declarados. Como posso fazer isso?
[b:9b7f98727f]2. Apagar Imagem do Banco de Dados: [/b:9b7f98727f]Tenho no programa também um botão pra apagar a imagem do Banco, caso ela tenha sido colocada erroneamente. Antes era fácil, era só apagar o Blob de texto e pronto, mas agora com a imagem gravada diretamente, como posso fazer isso?
[b:9b7f98727f]3. Alternar Entre Uma Imagem do Banco e Outra Fixa: [/b:9b7f98727f]Bom, esse caso é o último, hehe.. Eu usava esse sistema antes e gostaria de usar agora. Quando o banco não tem uma imagem selecionada, é mostrada um campo TImage como uma imagem padrão, escrito ´Sem Imagem´. Então, antes, quando o campo Blob da imagem tava vazio (texto), eu tornava o ´TImageBanco´ invisível e tornava o ´TImage´ visível, assim sempre mostrava uma imagem padrão quando o arquivo não tinha imagem. Como posso fazer isso usando o campo Blob type 2?
Agradeço qualquer ajuda deste tópico desde já..
Abraços..
Allan Elias Ramos :wink:
Aersoftware
Curtir tópico
+ 0Posts
24/07/2005
Bon Jovi
2. Pra apagar use o método Clear do TField.
3. Segue exemplo:
uses JPEG; procedure TDMTeste.CarregaImagem(BlobField: TBlobField; Image: TImage; ImagePadrao: TImage); var MemoryStream: TMemoryStream; JPEG: TJPEGImage; begin if BlobField.IsNull then begin Image.Picture.Assign(ImagePadrao.Picture); Exit; end; JPEG := TJPEGImage.Create; MemoryStream := TMemoryStream.Create; try BlobField.SaveToStream(MemoryStream); MemoryStream.Seek(0, soFromBeginning); JPEG.LoadFromStream(MemoryStream); if MemoryStream.Size > 0 then Image.Picture.Assign(JPEG) else Image.Picture.Assign(nil); finally JPEG.Free; MemoryStream.Free; end; end; Ex. de uso: CarregaImagem(TBlobField(ClientDataSet1.FieldByName(´arq_blob´)), Image1, Image2);
Outra opção é usar DBImage, que carrega automaticamente a imagem do banco. No evento AfterScroll do DataSet vc trataria a troca pela imagem ´padrao´.
Gostei + 0
24/07/2005
Aersoftware
Olá Bon Jovi. Nesse caso, o ´qryCadastro´ seria o componente TSQLDataSet ou seria o TClientDataSet? Como estou usando o dbExpress, eu usei o TClientDataSet. Ele esta num DataModule, então ficou assim o código:
Quando o usuário clicar no botão pra carregar a imagem, ele faz isso:
if OpImagem.Execute then begin (DmDados.ClientNacionais.FieldByName(´CAPA´) as TBlobField).LoadFromFile(OpImagem.FileName); end;
E o erro que dá é esse:
[Error] UCadNacionais.pas(659): Undeclared identifier: ´TBlobField´ [Error] UCadNacionais.pas(659): Undeclared identifier: ´LoadFromFile´ [Fatal Error] ProjHqmx.dpr(23): Could not compile used unit ´UCadNacionais.pas´
Eu dei uma olhada no campo ´CAPA´, que é o campo Blob pra salvar a imagem e na propriedade BlobType, ta como ´ftMemo´.. não sei se isso muda alguma coisa, mas antes, esse campo tava como Blob Text, depois mudei no Banco pra Blob Binary. Já tentei mudar esse BlobType pra ´ftBlob´ e pra ´ftTypedBinary´, mas o erro persiste.
Allan Elias Ramos :wink:
Gostei + 0
24/07/2005
Bon Jovi
E o BlobType correto é ftBlob mesmo.
Gostei + 0
24/07/2005
Aersoftware
E o BlobType correto é ftBlob mesmo.[/quote:70350a02e3]
Olá Bon Jovi, obrigado. Funcionou depois que coloquei a a unit DB. Mas agora ele me dá um erro quando seleciono a imagem. É o seguinte:
Eu já adiconei a unit Jpeg no uses e formatei o OpenPictureDialog pra exibir somente arquivos JPG ou JPEG. Geralmente os arquivos que tenho, e esse q tento colocar é extensão JPG.. O q pode ser isso?
Allan Elias Ramos :wink:
Gostei + 0
25/07/2005
Daemon
flws..
Gostei + 0
25/07/2005
Aersoftware
Descobri agora que o DBImage não suporta JPG, é verdade? Um formato tão comum.. Tem alguma alternativa a ele, nativa do Delphi? Eu sei q o EDBImage suporta, mas deu um problema na hora de eu instalar ele. Diz que falta um arquivo, se não me engano é o Configuration.inc. Aguém que já instalou aconteceu a mesma coisa?
Allan Elias Ramos :wink:
Gostei + 0
25/07/2005
Bon Jovi
Dependendo do tipo de acesso pode até ser bom. Mas se for via diretório compartilhado na rede aí pode ser furada, ficaria sem segurança, pois o usuário pode modificar ou apagar todos os arquivos diretamente pelo Windows. Outra desvantagem é que guardando em diretório vc perde a integridade referencial com os dados.
Suporta, segue aí exemplo:
procedure TForm1.EscolheImagem(Imagem: TDBImage); var oJPEG: TJPEGImage; oDialogo: TOpenPictureDialog; oPicture: TPicture; begin if not Assigned(Imagem) then Exit; if (not Assigned(Imagem.DataSource)) or (Imagem.DataField = ´´) then Exit; if not Assigned(Imagem.DataSource.DataSet) then Exit; if not (Imagem.DataSource.DataSet.Active) then Exit; oDialogo := TOpenPictureDialog.Create(nil); try oDialogo.Options := [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]; oDialogo.Filter := ´Imagens (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp´; oPicture := TPicture.Create; try oJPEG := TJPEGImage.Create; try if oDialogo.Execute then begin oPicture.LoadFromFile(oDialogo.FileName); oJPEG.Assign(oPicture.Graphic); if not (Imagem.DataSource.DataSet.State in dsEditModes) then Imagem.DataSource.DataSet.Edit; Imagem.Picture.Graphic.Assign(oJPEG); end; finally FreeAndNil(oJPEG); end; finally FreeAndNil(oPicture); end; finally FreeAndNil(oDialogo); end; end; procedure TForm1.Button1Click(Sender: TObject); begin EscolheImagem(DBImage1); end;
Gostei + 0
25/07/2005
Aersoftware
Mas ocorreu um erro estranho. Eu instalei o componente, tentei algumas vezes até dar certo, mas funcionou.
Quando eu coloquei ele no Form, que é igual ao DBImage, ele deu um erro na hora de salvar. Não lembro direito qual mensagem exatamente foi, mas pelo que entendi, ele dizia que não achava os componentes de acesso, que estavam no DataModule. Bom, retirei o componente, saí do projeto, abri denovo e inseri.. aí o form todo nao acha o DataModule. Fiz com que achasse e funcionou perfeito, mas um erro persiste. Eu tenho nesse form dois campos lookup, um listando grupos e outro subgrupos. de duas tabelas diferentes. Só que, o primeiro que ele deveria listar, que é o de grupos, ele fica inativo. Tem vários grupos cadastrados, mas ele nao lista nenhum. Já tentei recriar o LookUp, mas não funciona. Isso ja aconteceu comigo antes, mas nao lembro como resolver. Por acaso já aconteceu com vc? Do LookUp estar ali, mas parecer que esta desativado?
Allan Elias Ramos :wink:
Gostei + 0
26/07/2005
Aersoftware
procedure TForm1.EscolheImagem(Imagem: TDBImage); var oJPEG: TJPEGImage; oDialogo: TOpenPictureDialog; oPicture: TPicture; begin if not Assigned(Imagem) then Exit; if (not Assigned(Imagem.DataSource)) or (Imagem.DataField = ´´) then Exit; if not Assigned(Imagem.DataSource.DataSet) then Exit; if not (Imagem.DataSource.DataSet.Active) then Exit; oDialogo := TOpenPictureDialog.Create(nil); try oDialogo.Options := [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]; oDialogo.Filter := ´Imagens (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp´; oPicture := TPicture.Create; try oJPEG := TJPEGImage.Create; try if oDialogo.Execute then begin oPicture.LoadFromFile(oDialogo.FileName); oJPEG.Assign(oPicture.Graphic); if not (Imagem.DataSource.DataSet.State in dsEditModes) then Imagem.DataSource.DataSet.Edit; Imagem.Picture.Graphic.Assign(oJPEG); end; finally FreeAndNil(oJPEG); end; finally FreeAndNil(oPicture); end; finally FreeAndNil(oDialogo); end; end; procedure TForm1.Button1Click(Sender: TObject); begin EscolheImagem(DBImage1); end;
Amigo Bon Jovi. Fico muito grato com a sua ajuda. Depois de instalar e desinstalar o EDBImage, ver mensagens de erro na hora de botar a imagem e etc, usando o código acima que vc postou, funcionou. Consigo agora inserir e visualizar a imagem.
O único problema que ficou foi que o LookUp trancou, mas vou abrir um novo tópico pra perguntar sobre isso, pra nao poluir esse com outro assunto.
Só gostaria de fazer mais duas perguntinhas. Tem como dar uma explicadinha nas linhas desse código acima? Eu fiquei meio perdido enquanto digitava ele, e personalizava no meu aplicativo, mas funcionou perfeitamente, na primeira tentativa. Se não for dar muito trabalho, é claro..
E a outra pergunta é, como o banco de dados, no caso o firebird, salva o nome da imagem? Ele gera um nome aleatório ou salva com o nome original do aqruivo? No caso da primeira opção, pra eu salvar com o nome original da imagem, eu teria q ter um campo de texto pra capturar esse nome?
Mais uma vez agradeço a ajuda. Obrigado.
Allan Elias Ramos :wink:
Gostei + 0
26/07/2005
Bon Jovi
Sobre o Firebird nao conheço ele nesse ponto, melhor postar num forum sobre ele. Mesmo em outro banco nunca me preocupei com isso, pois gravo o nome em um campo separado mesmo.
Segue a funcao comentada:
procedure EscolheImagem(Imagem: TDBImage); var oJPEG: TJPEGImage; oDialogo: TOpenPictureDialog; oPicture: TPicture; begin if not Assigned(Imagem) then //somente pra evitar erro do programador Exit; if (not Assigned(Imagem.DataSource)) or (Imagem.DataField = ´´) then //somente pra evitar erro do programador Exit; if not Assigned(Imagem.DataSource.DataSet) then //somente pra evitar erro do programador Exit; if not (Imagem.DataSource.DataSet.Active) then //somente pra evitar erro do programador Exit; oDialogo := TOpenPictureDialog.Create(nil); //instancia um TOpenPictureDialog. Fiz isso pra função ficar mais isolada, mas prefira colocar no form direto ou deixe um sempre instanciado try oDialogo.Options := [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]; //opções da janela de diálogo do Windows, nem lembro pq coloquei isso nao tao fazendo sentido nesse caso oDialogo.Filter := ´Imagens (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp´; //filtra as extensões jpg, jpeg e bmp oPicture := TPicture.Create; //instancia um TPicture try oJPEG := TJPEGImage.Create; //instancia um TJPEGImage try if oDialogo.Execute then //executa a janela de dialogo do Windows begin oPicture.LoadFromFile(oDialogo.FileName); //carrega o arquivo escolhido na janela de dialogo no TPicture oJPEG.Assign(oPicture.Graphic); //copia a imagem carregada do arquivo para o objeto do tipo TJPEGImage, se for bmp já converte pra Jpeg if not (Imagem.DataSource.DataSet.State in dsEditModes) then Imagem.DataSource.DataSet.Edit; //deixa o DataSet editável, se nao tiver Imagem.Picture.Graphic.Assign(oJPEG); //copia a imagem JPEG para o TDBImage que é exibido pro usuario end; finally FreeAndNil(oJPEG); end; finally FreeAndNil(oPicture); end; finally FreeAndNil(oDialogo); end; end;
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)