[Dúvida] Salvar Imagem jpg no Firebird
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:
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?
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
Curtidas 1
Respostas
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.
Espero ter colaborado.
GOSTEI 0
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!
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
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
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
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
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
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.
Espero ter colaborado.
GOSTEI 0
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:
A pergunta sobre o seu codigo é a seguinte:
Esta parte e na contrucao do banco:
Este codigo e no Button:
E esta parte abaixo onde entra?
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
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:
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
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:
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
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!!
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
12/05/2011
Alguém pode me ajudar?
GOSTEI 0
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.
Espero ter colaborado.
GOSTEI 0
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.
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
12/05/2011
Alguém?
GOSTEI 0
Jore
12/05/2011
Por favor amigos me ajudem!
GOSTEI 0
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
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
12/05/2011
Alguém Por favor!!
GOSTEI 0
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 ;)
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
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>
</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