[Dúvida] Salvar Imagem jpg no Firebird

12/05/2011

0

Ola amigos,
Sou muito iniciante em Delphi e estou desenvolvendo um projeto pessoal onde tenho algumas poucas imagens que preciso salvar no banco de dados.
Estou conseguindo salvar usando o codigo abaixo:

procedure TForm1.btn1Click(Sender: TObject);
var
jpg:TJpegImage;
begin
if OpenPictureDialog.Execute then
begin
jpg := TJpegImage.Create();
jpg.LoadFromFile(OpenPictureDialog.FileName);
clipboard.Assign(jpg);
DBImage1.PasteFromClipboard;
jpg.Free;
end;
end;

Porem as imgens estao ficando com tamanhos gigantescos! Tem como reduzir o tamanho?

Estou utilizando um Banco Firebird (GDB) no Delphi 7;
Conexao feita no DataModule com IBTable, IBDatabese, IBTransaction e DataSource;
Um OpenPictureDialog, Um DBNavigator.

Mais uma duvida eh melhor eu usar um TDBImage ou um TDBIMG? Faz diferenca?
Jore

Jore

Responder

Posts

12/05/2011

Wilson Junior

As imagens no BD fica do mesmo tamanho que a imagem, ou seja, se vc tem uma imagem de 3mb, o banco irá gravar 3mb, ou seja, trafegará 3mb na rede.

Espero ter colaborado.
Responder

12/05/2011

Jore

Obrigado por sua ajuda amigo!

Porem eu estive olhando as imagens que usei nos testes e a maior imagem tem 125 kb e fiz uns 20 ou 30 testes. O banco esta com 44 mb. Tem algo errado no codigo? onde posso estar errando?

Vou criar tudo novamente e testar mais umas vezes e ponho os resultados aqui novamente apra os amigos me ajudarem.
Obrigado!
Responder

12/05/2011

Emerson Nascimento

o problema é que você está usando um DBImage. Esse componente trabalha com BMP, não importando o qual o tipo de imagem que você abra nele, ele converte pra BMP.

procure aqui no fórum. há vários tópicos com soluções para este problema.


https://www.devmedia.com.br/forum/delphi/130705-%5BDuvida%5D-Como-Salvar-Imagens-no-Banco-de-DAdos.html

https://www.devmedia.com.br/forum/delphi/385700-Ler-imagem-do-Banco-Firebird--BLOB.html



Responder

13/05/2011

Fernando Papile

EX: TABELINHA BANCO DE DADOS:
CREATE TABLE TB_PRODUTOS_FOTO (    FORNECEDOR  INTEGER NOT NULL,    PECA        VARCHAR(15) NOT NULL,    FOTO        BLOB SUB_TYPE 2 SEGMENT SIZE 80);
EX: GRAVAR NA TABELINHA
With DM.UpdateSql do  begin     CommandText:='INSERT INTO TB_PRODUTOS_FOTO (FORNECEDOR, PECA, FOTO) VALUES ('+     ':FORNECEDOR, :PECA, :FOTO)';     ParamByName('FORNECEDOR').AsInteger := 1;     ParamByName('PECA').AsString := '10';     ParamByName('FOTO').LoadFromFile('C:\TESTE.JPG',ftBlob);     execSql;  end;
EX: CARREGAR A FOTO GRAVADA NO COMPONENTE IMAGE
VarjpgImg: TJPEGImage;stMem: TMemoryStream;begin SqlFoto.Active := False; SqlFoto.CommandText := 'SELECT * FROM TB_PRODUTOS_FOTO '+ 'WHERE FORNECEDOR = 1 '+ ' AND PECA = 10'; SqlFoto.Active := True; If not sqlfoto.isempty Then  Begin   jpgImg := TJPEGImage.Create;   stMem := TMemoryStream.Create;   Try   SqlFotoFOTO.SaveToStream( stMem );   stMem.Position := 0;   jpgImg.LoadFromStream( stMem );   FotoProduto.Picture.Assign( jpgImg );   Finally   stMem.Free;   jpgImg.Free;   end;  End Else  Begin   //tratar aqui como nao encontrado  End; SqlFoto.Active := False;end;
At mais
 
Responder

13/05/2011

Wilson Junior

No firebird tem um detalhe, quando você exclui um registro de uma tabela, ele não aparecemais na tabela, mas o tamanho do banco não diminui, para diminuir o tamanho do banco, faça um backup e restore do mesmo.

Espero ter colaborado.
Responder

13/05/2011

Jore

Olá amigo Fernando Peres Papile,

Veja a imagem do meu projeto:

A imagem tem 40 kb o campo e DBImage;

No Button coloquei o codigo abaixo:
var
jpg:TJpegImage;
begin
if OpenPictureDialog.Execute then
begin
jpg := TJpegImage.Create();
jpg.LoadFromFile(OpenPictureDialog.FileName);
clipboard.Assign(jpg);
DBImage1.PasteFromClipboard;
jpg.Free;
end;
end;


 A pergunta sobre o seu codigo é a seguinte:

Esta parte e na contrucao do banco:

EX: TABELINHA BANCO DE DADOS:
CREATE TABLE TB_PRODUTOS_FOTO (    FORNECEDOR  INTEGER NOT NULL,    PECA        VARCHAR(15) NOT NULL,    FOTO        BLOB SUB_TYPE 2 SEGMENT SIZE 80);


Este codigo e no Button:

EX: CARREGAR A FOTO GRAVADA NO COMPONENTE IMAGE
VarjpgImg: TJPEGImage;stMem: TMemoryStream;begin SqlFoto.Active := False; SqlFoto.CommandText := 'SELECT * FROM TB_PRODUTOS_FOTO '+ 'WHERE FORNECEDOR = 1 '+ ' AND PECA = 10'; SqlFoto.Active := True; If not sqlfoto.isempty Then  Begin   jpgImg := TJPEGImage.Create;   stMem := TMemoryStream.Create;   Try   SqlFotoFOTO.SaveToStream( stMem );   stMem.Position := 0;   jpgImg.LoadFromStream( stMem );   FotoProduto.Picture.Assign( jpgImg );   Finally   stMem.Free;   jpgImg.Free;   end;  End Else  Begin   //tratar aqui como nao encontrado  End; SqlFoto.Active := False;end;


E esta parte abaixo onde entra?

EX: GRAVAR NA TABELINHA
With DM.UpdateSql do  begin     CommandText:='INSERT INTO TB_PRODUTOS_FOTO (FORNECEDOR, PECA, FOTO) VALUES ('+     ':FORNECEDOR, :PECA, :FOTO)';     ParamByName('FORNECEDOR').AsInteger := 1;     ParamByName('PECA').AsString := '10';     ParamByName('FOTO').LoadFromFile('C:\TESTE.JPG',ftBlob);     execSql;  end;



Responder

14/05/2011

Fernando Papile

é que no seu form vc usa o proprio componente dbnavigator e um dbimage para gerenciar a tabelinha de dados.
no meu caso eu fiz tudo manual via sql mesmo, e com um componente image dando um load no banco.
se vc quizer eu te envio o form e a unit pra vc dar uma olhada.
abraço
Foto do meu Form:

Responder

15/05/2011

Jore

é que no seu form vc usa o proprio componente dbnavigator e um dbimage para gerenciar a tabelinha de dados.
no meu caso eu fiz tudo manual via sql mesmo, e com um componente image dando um load no banco.
se vc quizer eu te envio o form e a unit pra vc dar uma olhada.
abraço
Foto do meu Form:




Fernado vou aceitar o seu form e edit para ver se eu consigo.  Obrigado!
Responder

17/05/2011

Jore

Fernando,

Meu e-mail e: jore4ever@gmail.com se voce puder me mandar o seu exemplo para eu poder entender onde estou errando...Obrigado desde ja!!
Responder

21/05/2011

Jore

Alguém pode me ajudar?
Responder

23/05/2011

Wilson Junior

De uma olhada neste site e veja se ajuda http://www.mail-archive.com/delphi-br@yahoogrupos.com.br/msg39517.html

Espero ter colaborado.
Responder

27/05/2011

Jore

De uma olhada neste site e veja se ajuda http://www.mail-archive.com/delphi-br@yahoogrupos.com.br/msg39517.html

Espero ter colaborado.


Ola Wilson,
Estou tentando seguir a sua dica porem estou meio enrrolado e espero que alguem possa me ajudar.

Abaixo como esta meu codigo:



unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ExtDlgs, IBDatabase, DB, IBCustomDataSet,
  IBTable, DBCtrls, Mask, JPEG, Consts;

  const
  OffsetMemoryStream : Int64 = 0;


type
  TTipoImagem = (tiBitmap, tiJpeg);
  TForm1 = class(TForm)
    Image1: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    Button1: TButton;
    IBTable1: TIBTable;
    IBDatabase1: TIBDatabase;
    IBTransaction1: TIBTransaction;
    DataSource1: TDataSource;
    IBTable1CODIGO: TIntegerField;
    IBTable1NOME: TIBStringField;
    IBTable1IMG: TBlobField;
    Label1: TLabel;
    DBEdit1: TDBEdit;
    Label2: TLabel;
    DBEdit2: TDBEdit;
    Label3: TLabel;
    DBNavigator1: TDBNavigator;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);


  private
  procedure ExibeFoto(DataSet : TDataSet; BlobFieldName : String; ImageExibicao :TImage);
procedure GravaFoto(DataSet : TDataSet; BlobFieldName, OpenPictureDialog1 : String);
procedure ExcluiFoto(DataSet : TDataSet; BlobFieldName : String);
procedure ExportaFoto(DataSet : TDataSet; BlobFieldName, OpenPictureDialog1 : String;TipoImagem : TTipoImagem);

    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  MemoryStream : TMemoryStream;
  Jpg : TJpegImage;
  Bitmap : TBitmap;


implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin

if OpenPictureDialog1.Execute then
image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

end;

procedure TForm1.ExcluiFoto(DataSet: TDataSet; BlobFieldName: String);
begin
  if (Ibtable1.State in [dsEdit,dsInsert])
  and not((Ibtable1.FieldByName(BlobFieldName) as TBlobField).IsNull) then
    (DataSet.FieldByName(BlobFieldName) as TBlobField).Clear;
//para limpar o TImage use
// Image1.Picture := Nil;
end;


procedure TForm1.ExibeFoto(DataSet: TDataSet; BlobFieldName: String;
  ImageExibicao: TImage);
begin
  if not(Ibtable1.IsEmpty) and
  not((Ibtable1.FieldByName(BlobFieldName) as TBlobField).IsNull) then
    try
      MemoryStream := TMemoryStream.Create;
      Jpg := TJpegImage.Create;
      (Ibtable1.FieldByName(BlobFieldName) as
TBlobField).SaveToStream(MemoryStream);
      MemoryStream.Position := OffsetMemoryStream;
      Jpg.LoadFromStream(MemoryStream);
      Image1.Picture.Assign(Jpg);
    finally
      Jpg.Free;
      MemoryStream.Free;
    end
  else
  // o Else faz com que, caso o campo esteja Null, o TImage seja limpado
    ImageExibicao.Picture := Nil;
end;


procedure TForm1.ExportaFoto(DataSet: TDataSet; BlobFieldName,
  OpenPictureDialog1: String; TipoImagem: TTipoImagem);
begin

end;

procedure TForm1.GravaFoto(DataSet: TDataSet; BlobFieldName,
  OpenPictureDialog1: String);
var
  ext : string;
begin
  if (Ibtable1.State in [dsEdit,dsInsert]) then begin
    ext := UpperCase(ExtractFileExt(OpenPictureDialog1));
    if (ext <> '.BMP') and (ext <> '.JPG') and (ext <> '.JPEG') then begin
     raise EAccessViolation.Create('Formato de imagem não suportado! Formato suportado: Jpeg ou Bitmap');
      Abort;
    end;
    try
      Jpg := TJpegImage.Create;
      MemoryStream := TMemoryStream.Create;
      Bitmap := TBitmap.Create;
      if (ext = '.BMP') then begin
        Bitmap.LoadFromFile(OpenPictureDialog1);
        Jpg.Assign(Bitmap);
        Jpg.Compress;
      end else
        Jpg.LoadFromFile(OpenPictureDialog1);
      Jpg.SaveToStream(MemoryStream);
      MemoryStream.Position := OffsetMemoryStream;
      (Ibtable1.FieldByName(BlobFieldName) as TBlobField).BlobType :=
ftTypedBinary;
      (Ibtable1.FieldByName(BlobFieldName) as
TBlobField).LoadFromStream(MemoryStream);
    finally
      MemoryStream.Free;
      Bitmap.Free;
      Jpg.Free;
    end;
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
If Ibtable1.State in [DsEdit,Dsinsert] then
       GravaFoto(Ibtable1,'IMG',OpenPictureDialog1.FileName); // aqui seleciona uma jpg

end;

end.



Coloquei um botao Exibir Foto para abrir a imagem e coloquei o codigo(O codigo abaixo, ja consta no codigo acima ):


if OpenPictureDialog1.Execute then
image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);






Os componentes da imagem acima sao:

Um componente TImage
Um componente TButton
Um componente OpenPictureDialog
Um componente IBDatabase
Um componente IBTransaction
Um componente IBTable
Um componente DataSource
Um componente DBNavigator
Um Banco de Dados Firebird com tres campos CODIGO, NOME E IMG

As modificacoes que fiz no codigo foram as seguintes:

Troquei FileName por OpenPictureDialog1

Troquei  DataSet por Ibtable1

Agora o projeto esta rodando so nao acontece nada. (Ta carregando a imagem tanto jpg quanto bmp com o comando do botao exibir imagem e ta salvando os campos nome e codigo.)

Se eu fechar o projeto e abrir novamente a imagem some.
Se eu carregar a imagem e mudar para o cadastro 2 a imagem continua a mesma.

Me ajudem por favor!  e Obrigado é claro!
Responder

31/05/2011

Jore

Alguém?
Responder

03/06/2011

Jore

Por favor amigos me ajudem!
Responder

06/06/2011

Nigro

Não seria o ideal deixar imagens fora da base, gravando apenas o caminho e no form você coloca um componente não DB, fazendo um load from file para a exibição?
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar