[Dúvida] Salvar Imagem jpg no Firebird

Delphi

12/05/2011

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

Curtidas 1

Respostas

Wilson Junior

Wilson Junior

12/05/2011

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.
GOSTEI 0
Jore

Jore

12/05/2011

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!
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

12/05/2011

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



GOSTEI 0
Fernando Papile

Fernando Papile

12/05/2011

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
 
GOSTEI 0
Wilson Junior

Wilson Junior

12/05/2011

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.
GOSTEI 0
Jore

Jore

12/05/2011

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;



GOSTEI 0
Fernando Papile

Fernando Papile

12/05/2011

é 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:

GOSTEI 0
Jore

Jore

12/05/2011

é 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!
GOSTEI 0
Jore

Jore

12/05/2011

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!!
GOSTEI 0
Jore

Jore

12/05/2011

Alguém pode me ajudar?
GOSTEI 0
Wilson Junior

Wilson Junior

12/05/2011

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

Espero ter colaborado.
GOSTEI 0
Jore

Jore

12/05/2011

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!
GOSTEI 0
Jore

Jore

12/05/2011

Alguém?
GOSTEI 0
Jore

Jore

12/05/2011

Por favor amigos me ajudem!
GOSTEI 0
Nigro

Nigro

12/05/2011

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?
GOSTEI 0
Jore

Jore

12/05/2011

Nao seria o ideal deixar imagens fora da base, gravando apenas o caminho e no form voce coloca um componente nao DB, fazendo um load from file para a exibicao?

Nao amigo, tenho que salvar no banco mesmo e este metodo que o amigo Wilson Lehapan, me passou parece ser otimo pois faz a compressao da imagem e salva em jpg e tuqdo que eu quero so falta funcionar...Continuo na busca e Obrigado a todos!
GOSTEI 0
Jore

Jore

12/05/2011

Alguém Por favor!!
GOSTEI 0
Jhonatan Pereira

Jhonatan Pereira

12/05/2011

Embora a questão seja antiga, caso alguém na internet caia nesse tópico vai servir de ajuda.
Ao invés de salvar a imagem no banco de dados, salve-a em um local e grave no banco de dados apenas o endereço da imagem.

Ex.: LOCAL:
Se a imagem for salva em 'C:\seuprograma\imagens'
salve no banco de dados o endereço 'C:\seuprograma\imagens\foto.jpg'

REMOTO
Se a imagem for salva em 'http://www.seusite.com.br/imgs/'
salve no banco de dados o endereço 'http://www.seusite.com.br/imgs/foto.jpg'

Além de economizar (e muito!) o tempo de processamento, você fará algo mais profissional e poupará seu BD ;)
GOSTEI 0
Edivaldo B

Edivaldo B

12/05/2011

é que no seu form vc usa o proprio componente dbnavigator e um dbimage para gerenciar a tabelinha de dados.<div>
</div><div>no meu caso eu fiz tudo manual via sql mesmo, e com um componente image dando um load no banco.</div><div>
</div><div>se vc quizer eu te envio o form e a unit pra vc dar uma olhada.</div><div>
</div><div>abraço</div><div>
</div><div>Foto do meu Form:</div><div>
</div><div><img src="../imagens/articles/202153/fototela.jpg" border="" width="491" height="378">
</div>


Amigo, estou precisando de um exemplo, pode me enviar?
edijovem@gmail.com
GOSTEI 0
POSTAR