Achei varios exemplos na internet mais todos eles é criado um campo string para inserir 1 unica imagem, e eu presiso poder inserir quantas imagens forem necessarias em cada registro, podem ser 1, 5 ou 30 por exemplo.
Alguem saberia explicar como fazer isso usando o caminho das imagens? Vou ter que criar 30 campos string na tabela de imoveis e armazenar o caminho de cada foto em um campo? ou tem algum outro metodo mais eficaz e pratico?
Aceito qualquer sugestão que me ajude a inserir varias imagens no mesmo registro, teria que crirar também um sistema pratico para mostrar as fotos de cada Imovel.
[ImagensPredioCod001.INI]
conteúdo:
[Imagens]
CodigoImagem01 = "C:\Diretorio\ImagemTal.bmp"
CodigoImagem02 = "C:\Diretório\ImagemTal2.bmp"
Assim vc so grava na base de dados o arquivo diretorio do arquivo ini que contem todos os demais diretorios de imagens. Eu utilizo este método e meu sistema não fica lerdo. Agora existe outros metodos que se pode aplicar,
porem estou sugerindo este.
Dê uma olhada no help do delphi como funciona os arquivos INI, caso se interesse pelo método. E se precisar de exemplo... neste forum e no antigo forum daqui há muita informação pronta. basta dar um search.
qualquer coisa basta dar o grito.
Abs,
pjrm1470.
Ainda estou na busca de mais ideia ja que para o .INI mais arquivos vão ter que ser criados a cada conjunto de imagens inseridas, eu queria usar o minimo possivel de de arquivos, por isso até estou usando Access, se fosse o Firebird ou Mysql ja exigiria a instalação do cliente no computador do usuario.
Se tiver um link para um exemplo ou explicação de gravar imagem com esses componentes também ajudaria muito.
Os campos é pra criar no Access e puxar para o ClientDataSet ou criar nele mesmo? que arquivo é esse .cds? como crio um?
No aguardo.
Coloque no formulário um componente ClientDataSet da palheta Data Access e altere sua propriedade Name para CdsFotosImoveis. De um clique na propriedade FieldDefs e outro clique nas reticências ao lado da propriedade. Será aberta a janela Editing CdsFotosImoveis. FieldDefs, clique três vezes no botão Add New na parte superior da janela.
Selecione cdsFotosImoveisField1 e altere as seguintes propriedades:
Name: id
DataType: ftAutoInc
Selecione cdsFotosImoveisField2 e altere as seguintes propriedades:
Name: CodImovel
DataType: ftInteger
Selecione cdsFotosImoveisField3 e altere as seguintes propriedades:
Name: Foto
DataType: ftBlob
Clique novamente com o botão direito do mouse sobre o ClientDataSet e depois em Fields Editor...
Clique com o botão direito do mouse sobre o Fields Editor e depois em Add all fields.
O caminho no filename fico A:\Projetos\Imobiliaria\FotosClientes.cds, pensei que o arquivo seria criado depois de salvar mas por enquanto so aparece o .exe la.
query que pega os dados do Imovel é a "ADOQImoveis"
Campos da tabela "Imoveis":
ADOQImoveisID: AutoIncField;
TipodeImvel: WideStringField;
Referencia: WideStringField;
Endereço: WideStringField;
Bairro: WideStringField;
Cidade: WideStringField;
Edificio: WideStringField;
DCE: BooleanField;
Lavado: BooleanField;
Banheirodeservo: BooleanField;
Cozinha: BooleanField;
Copa: BooleanField;
AreadeServiço: BooleanField;
Quartodedespejo: BooleanField;
Piscina: BooleanField;
Obspagamento: MemoField;
Quartos: IntegerField;
Suites: IntegerField;
Banheiros: IntegerField;
AreaExterna: BooleanField;
VagasdeGaragem: IntegerField;
CondiodePagamento: WideStringField;
Valor: IntegerField;
ObsOpcionista: MemoField;
Opcionista2: WideStringField;
Opcionista: WideStringField;
Parte referente aos dados do proprietario(também presente na tabela imoveis):
Nome: WideStringField;
Profissão: WideStringField;
Endereço: WideStringField;
Identidade: WideStringField;
CPF: WideStringField;
Telefone: WideStringField;
Celular: WideStringField;
Conjuje: WideStringField;
Observações: MemoField;
Sugiro que troque o caminho pelo menos do arquivo CDS para C:\, pois, quando for instalar no seu cliente ele terá de ter o drive A:\ senão vai dar erro.
De qualquer modo ja mudei pra C:\Imob\Banco de Imagens\FotosImoveis.cds
Sobre a tabela eu conversei com chefe da imobiliaria que minha mãe trabalha quando ele pediu o programa, ei iria criar a tabela "cliente" aonde ele cadastraria tanto pessoas interessadas como proprietarios e na hora do cadastro de Imoveis ele so teria que escolher o cliente(dono do imovel) em um combobox.
Ele não gostou e preferiu que fosse exatamente igual ao que eles prenchem na ficha de cadastro deles. E como o cliente é quem manda.......fiz do jeito que você viu acima.
Como é uma imobiliaria de pequeno porte(4 corretores) e não existe um planejamento para expandir mais do que isso não creio que havera muitos casos de repetição de dono de imovel, em uma de grande porte seria bem inviavel esse sistema que eles utilizam.
Alias essa é a terceira vez que tento ajudar a melhorar um sistema e me pedem pra deixar exatamente como era quando não utilizavam computador. Fiquei bem frustrado quando dividi uma ficha de hospital volunario em 6 tabelas(Medicos,, Volunarios, Motoristas, ect) pra eles poderem escolher em um combobox e me pediram pra deixar como era, ou seja, 1 tabela unica. A unica melhora que tiveram foi um sistema de busca mais rapido do que procurar no papel no fim das contas ¬¬ .
Bom, fico no aguardo da continuação do tutorial.
Vamos realizar o relacionamento entre ADOQImoveis e cdsFotosImoveis:
Coloque um datasource para o cdsFotosImoveis.
Selecione o cdsFotosImoveis e na propriedade MasterSource escolha o datasource ligado ao ADOQImoveis.
Na propriedade MasterFields, clique nas reticências, ligue ID de ADOQImoveis com CodImovel do cdsFotosImoveis.
Pronto relacionamento entre as duas tabelas realizado, pode ser feito pelo afterScroll do ADOQImoveis também.
Inserindo uma foto:
Inclua um OpenPictureDialog da palheta Dialogs.
Inclua um botão com o caption inserir imagem do imóvel e no seu evento onclick digite:
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Insert;
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
Mostrando a foto:
Coloque um DBCtrlGrid da palheta Data Controls.
Ligue sua propriedade DataSource com o Datasource ligado a cdsFotosImoveis.
Dentro do DBCtrlGrid, coloque um DBImage da palheta Data Controls.
Ligue sua propriedade DataSource com o Datasource ligado a cdsFotosImoveis.
Ligue sua propriedade DataField com o campo Foto.
Coloque False em AllowDelete e AllowInsert para que o usuário não exclua e nem inclua diretamente pelo DBCtrlGrid.
Se quiser pode colocar um botão para alterar a foto do imóvel, basta que antes disso você selecione a foto no DBCtrlGrid:
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Edit;
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de Editar uma foto');
Abort;
end;
Deletando a foto, basta que antes disso você selecione a foto no DBCtrlGrid:
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
if not(cdsFotosImoveis.IsEmpty) then
cdsFotosImoveis.Delete
else
begin
ShowMessage('Não há foto para excluir');
Abort;
end;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de Editar uma foto');
Abort;
end;
o erro é esse:
"Project Imob.exe raised exception class EFOOpenError with message 'Cannot open file'. The filename, directory name, or volume label syntax is incorrect'. Process stopped. Use Step or Run to continue."
Inserindo uma foto:
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Insert;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
Se quiser pode colocar um botão para alterar a foto do imóvel, basta que antes disso você selecione a foto no DBCtrlGrid:
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Edit;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de Editar uma foto');
Abort;
end;
2 duvidas/problemas que apareceram agora:
1 - Como fazer para poder adicionar imagens Jpeg? pensei que era so adicionar o jpeg no Uses mas não é tão simples assim ao que parece.
2 - o DBimage ou deixa as imagens no tamanho original ou as expande para o tamanho maximo dele se o Strecth for True, o problema é que nem toda imagem tem as mesmas proporções(se bem que em termos de so fotos de casas deve ter sim, mas não custa ja perguntar) ae quando uma imagem é 100x50 por exemplo e meu DBImage é 100x100 a imagem é esticada e fica disforme, e seu eu deixar o Stretch False e colocar uma imagem 400x400 so vai aparecer 1/4 da imagem ja que é 100x100 o DBimage, existe alguma solução para isso?
Declare jpeg, clipbrd no Uses.
Inserir uma imagem:
var
jpg: Tjpegimage;
begin
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Append;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
begin
jpg:= Tjpegimage.Create;
jpg.LoadFromFile(openpictureDialog1.FileName);
Clipboard.Assign(jpg);
Dbimage1.PasteFromClipboard;
jpg.Free;
end;
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;
Editar uma imagem
var
jpg: Tjpegimage;
begin
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Edit;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
begin
jpg:= Tjpegimage.Create;
jpg.LoadFromFile(openpictureDialog1.FileName);
Clipboard.Assign(jpg);
Dbimage1.PasteFromClipboard;
jpg.Free;
end;
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;
O deletar ta funcionando certinho também, no caso so coloquei
cdsFotoImoveis.Edit;
cdsFotoImoveis.Delete;
Outra duvida agora. No DBctrlGrid tem como comandar a barra de rolagem por codigo? to querendo montar um Form para Mostrar as imagens em tamanho grande, pra mostrar em tamanho grande eu puxei a variavel Foto do Fields do ClienteDataSet mas não sei como fazer passar as imagens pra frente ou para tras sem ficar clicando manualmente na barra de rolagem do BDCtrlGrid e o que eu queria era um botão pra ficar passando as imagens pra frente e para tras.
Cancela o que eu disse acima, ocorreram alguns novos problemas.
1 - Quando deleto um imovel gostaria que todas as imagens relacionadas a ele fossem deletadas também como seria o comando para deletar o registro em cdsFotosImoveis ligado ao registro no banco de dado do access?
2 - Mesmo depois de deletar as imagens eles não parecem ter sido removidas do arquivo .cds ja que ele não diminui de tamanho.
3 - Eu coloco uma imagem de 300KB e o .CDS aumenta em mais de 1 MB de tamanho, isso é normal?
4 - Agora quando tento colocar uma imagem bmp da erro no programa, ele so aceita jpeg, não que isso seja um problema ja que as fotos de imobiliaria são todas em jpeg mesmo, mas gostaria de saber como contornar isso para programas futuros.
JPG
var
jpg: Tjpegimage;
begin
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Append;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
begin
if radiogroup1.ItemIndex = 1 then
begin
jpg:= Tjpegimage.Create;
jpg.LoadFromFile(openpictureDialog1.FileName);
Clipboard.Assign(jpg);
Dbimage1.PasteFromClipboard;
jpg.Free;
end
else
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
end;
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;
var
jpg: Tjpegimage;
begin
if not(ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
cdsFotosImoveis.Edit;
OpenPictureDialog1.InitialDir := 'C:\Imob\Banco de Imagens';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
begin
if radiogroup1.ItemIndex = 1 then
begin
jpg:= Tjpegimage.Create;
jpg.LoadFromFile(openpictureDialog1.FileName);
Clipboard.Assign(jpg);
Dbimage1.PasteFromClipboard;
jpg.Free;
end
else
cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
end;
cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;
Vlw, Funcionou, testei usar so ele sem deletar o imovel e removeu todas as fotos.
So vai ficar em aberto o problema do aquivo ".cds" que aloca as imagens, não diminuir de tamanho(ou voltar a 1kb no quando deleto tudo no presente caso), eu coloquei varios imoveis com fotos, e foi pra 40MB, deletei tudo e continua com 40MB. Quando acrescento novos imoveis continua aumentando, foi pra 48MB no caso.
Alguem sabe explicar porque esse ".cds" fica tão grande?, ele ta multiplicando por 10x o tamanho das imagens, ta impossivel, coloquei 10 imagens de 2MB e o arquivo foi pra 200MB, não tem HD que aguente, alguem sobe como resolver ou modificar esse problema?
Coloquei umas 30 imagens e deu um erro de memoria quando fechei o programa, não sei o motivo.
Do modo anterior estava impossivel, 20MB de imagem virando 200MB, o programa lagava muito quando exibia as imagens no CtrlGrid, estranhamente ele da ainda mais lag quando usei o access para guardar as imagens JPEG, 20MB virou 40MB no access no entanto eu tinha lags de 5s ou mais nos botões nos forms com imagens.
EDBImage:
Esse componente tem propriedades para redimencionar as imagens sosinho, ou seja não importa a resolução, pode ser qualquer uma. E ele aceita qualquer tipo de imagem evitando a necessidade de converter para bmp.
De resto ele funciona igual ao DBImage.
Segue o codigo para gravar com clientdataset alterado abaixo, tirei apenas as partes de conversão para JPEG para BMP ja que o EDBImage não presisa disso.
Adicionar imagem:
[CODE]
begin
if not(DM.ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
DM.cdsFotosImoveis.append;
OpenPictureDialog1.InitialDir := 'A:\Projetos\Imobiliaria';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
DM.cdsFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
DM.cdsFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;[/CODE]
Fiz algo errado?
Abaixo o codigo que usei para guardar as imagens no access, funcionou mas fica muito lagado o programa.
[CODE]
begin
if not(DM.ADOQImoveis.State in [dsEdit, dsInsert]) then
begin
DM.ADOFotosImoveis.insert;
OpenPictureDialog1.InitialDir := 'A:\Projetos\Imobiliaria';{Verifique se este é o caminho onde vais guardar as fotos}
if OpenPictureDialog1.Execute then
DM.ADOFotosImoveisFoto.LoadFromFile(OpenPictureDialog1.FileName);
DM.ADOFotosImoveis.Edit;
DM.ADOFotosImoveis.Post;
end
else
begin
ShowMessage('Salve os dados do imóvel antes de inserir uma foto');
Abort;
end;
end;[/CODE]
Sera que fica muito pesado ficar pegando as fotos do Banco de dados? no caso testei com imagens de 2MB que são bem grandes até.
Eriley teria como mostrar como ficaria seu codigo para pegar apenas o caminho da imagem ao invez da imagem em si?
Devido aos problemas que estou tendo em gravar a imagem diretamente no BD(ta ficando gidante e lagando o programa) vou tentar um outro metodo qeu descrevi no topico abaixo. Nele quero transferir a imagem pra uma pasta com Nomeada com o IDdoImovel no mesmo diretorio do executavel e gravar na BD o caminho até essa imagem.
O problema vai ser na hora se fazer um programa desatualizado se atualizar no programa principal do servidor, em vez de copiar um arquivo vom as imagens vai ter que copiar a pasta "Fotos" que contem todas as fotos cadastradas no programa. Mas um problema de cada vez.
Segue o link do outro topico aonde coloquei o que gostaria de fazer.
http://www.devmedia.com.br/forum/delphi/385511-Como-criar-pastas-e-mover-arquivos--jpeg-com-o-delphi.html








