Duvida como pegar, gravar e retornar imagem do banco (RESOLVIDO)

10 respostas
B

Ola pessoal, estou com uma duvida, será que podem me ajudar?? Pesquisei na internet e não achei algo explicativo
Tenho um sistema em java que será rodado em rede, um formulário de cadastro tem um atributo foto o qual será armazenado no banco, utilizo postgresql
A duvida é o seguinte… utilizo o JFileChooser para selecionar o arquivo, como eu faço para que o arquivo selecionado se torne um blob para que seja persistido em uma query?
e qdo for efetuar um select como recuperar a imagem do blob para que seja exibida no metodo listar?

Atualmente trabalhava com os arquivos fisicos e somente pegar o camnho do jJFileChooser e gravava em um atributo varchar, abaixo segue o codigo getfile()

private JFileChooser getFile(){
		if(file == null){
			file = new JFileChooser();
			file.showOpenDialog(null);
			foto = file.getSelectedFile().getPath();
		}
		else{
			file.showOpenDialog(null);
			foto = file.getSelectedFile().getPath();
		}
		return file;
	}

Ao olhar o código a cima nota-se que a linha: foto = file.getSelectedFile().getPath(); somente seleciona o caminho do arquivo

Por favor, me ajudem…

Desde já, agradeço

10 Respostas

G

Vc pode fazer de várias formas, com o caminho do arquivo crie um objeto File e grave ele no blob

Ou ainda você pode usar um ByteArrayInputStream e gravar o array de bytes no banco

Sugiro ainda criar um objeto Imagem para ser armazenado que implementa a interface Serializable se você quiser adicionar comportamento a imagem

A forma tanto faz desde que você transforme esse objeto de acordo quando ler.

G

Olá

O que você precisa é ler o arquivo de imagem, coisa que vai conseguir fazer utilizando a classe java.io.FileInputStream. Ela pede um objeto java.io.File no seu construtor, que você obtém do seu JFileChooser pelo método getSelectedFile. Note que o JFileChooser é só o ‘escolhedor’ de arquivos, e não algo que aponte para o arquivo em si. O seu método getFile(), pela lógica, deveria retornar uma instância de um java.io.File. Algo assim:

public File getFoto(){
    JFileChooser fileChooser = new JFileChooser();
    int answer = fileChooser.showOpenDialog(null);
    if(answer == APPROVE_OPTION) {
        return fileChooser.getSelectedFile();
    }
}

Agora, para salvar isso no seu banco de dados, depende de como você está fazendo acesso a ele… via Hibernate, PreparedStatement… dê uma olhada na documentação. Em uma abordagem usando ResultSets você provavelmente vai usar updateBlob(String columnLabel, InputStream inputStream), que aceita o FileInputStream que você cria com o File retornado pelo seu método.

Sds.,
Guilherme

B

Olá caros colegas
Já utilizo esse padrão para pegar a imagem, porém no postgresql9 não temos o tipo image e para blob temos 2 tipos, oid e bytea, estou utilizando bytea e o meu padrão de acesso a dados por MVC utilizo o statment of transaction e para persistir um insert eu passo o objeto recuperado do formulário abrindo uma transaction onde o postgre que é conectado todo o momento recebe um objeto onde um do seus atrtibutos é o buffer da imagem e outro atributo é o tipo dela, dessa forma ele persiste ao executar um query contendo o objeto populado e ao processo ser efetuado retorna commit ou roldback. A insert funciona normalmente, o problema é qdo vou recuperar o buffer da imagem que o objeto bufferimager está sempre retornando null mesmo tendo a array da imagem retornada do banco.

Esse mesmo processo fiz no Oracle 11g, gravando com blob e o bufferimage que é binário da imagem retorna um array blob bufferisado onde recupera a imagem e converto para IO image e consigo exibi-lo. O que não ocorre no postgre.

Atualmente estou gravando o buffer da imagem, file da imagem e o tipo, crio um arquivo virtual temporário e passo esse arquivo para ser exibido no formulário, porém isso é gambiarra né

Alguém tem uma ideia, como gravar imagem de outra forma para seja recuperado no objeto.lista(); onde esse objeto recupera de um select os dados do postgresql e constrói o objeto contendo os dados e a imagem para ser exibida no painel?

Desde já, agradeço

G

Olá pessoal!

Estou com dificuldade de pegar o caminho da imagem e inserir no banco MySql.
Eu já consegui abrir essa imagem e exibi-la em uma jlabel usando jFileChooser, mas agora eu preciso cadastrar esse caminho e guardar essa imagem em um diretório do meu sistema.

Se puderem ajudar eu agradeço…
Abraço

G

Olá pessoal!

Consegui capturar o caminho da img e exibi-la na redimensionada minha jlabel.
Segue abaixo o codigo que eu utilizei. (Obs. Se alguem tiver alguma sugestão de melhorar o código eu agradeço!)

JFileChooser arquivo = new JFileChooser();    
          arquivo.setDialogTitle("Selecione a Imagem");    
          arquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);    
          FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images", new String[]{"jpg","png"});    
          arquivo.setFileFilter(filter);          
          arquivo.setAcceptAllFileFilterUsed(false);  
          arquivo.setMultiSelectionEnabled(false);    
          File file = new File("user.dir");    
          int option = arquivo.showOpenDialog(this);
          PessoasDAO pDao = new PessoasDAO();
          if(option == JFileChooser.APPROVE_OPTION) {
              String caminhoArquivo = "";
              caminhoArquivo = arquivo.getSelectedFile().getAbsolutePath();
              file = arquivo.getSelectedFile();  
              String nomeArquivo = file.getName();  
              int e = nomeArquivo.lastIndexOf(".");  
              String extensao = nomeArquivo.substring(e);
              Image image = null;
              try {
                  image = ImageIO.read(file);
              } catch (IOException ex) {
                  Logger.getLogger(CadPessoas.class.getName()).log(Level.SEVERE, null, ex);
              }
              if(extensao.equals(".jpg") || extensao.equals(".JPG")){
                    lblFoto.setIcon(new ImageIcon(arquivo.getSelectedFile().getAbsolutePath()));
                    lblNomeFoto.setText(caminhoArquivo);
                    lblFoto.setIcon(new ImageIcon(image.getScaledInstance(lblFoto.getWidth(),lblFoto.getHeight(), image.SCALE_DEFAULT)));  

              }else{  
                  JOptionPane.showMessageDialog(null, "Arquivo não suportado", "Erro", JOptionPane.ERROR_MESSAGE);  
              }      
          }

Agora na hora de mostrar todos os dados do meu frame, eu preciso exibir a imagem que foi cadastrada junto a pessoa.
(Lembrando que no banco só está cadastrado na minha tabela Pessoa o caminho da minha imagem)
Se alguém puder ajudar eu agradeço…

Abraço e bons estudos a todos…

V

GuilhermeSilva:
Olá pessoal!

Consegui capturar o caminho da img e exibi-la na redimensionada minha jlabel.
Segue abaixo o codigo que eu utilizei. (Obs. Se alguem tiver alguma sugestão de melhorar o código eu agradeço!)

JFileChooser arquivo = new JFileChooser();    
          arquivo.setDialogTitle("Selecione a Imagem");    
          arquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);    
          FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images", new String[]{"jpg","png"});    
          arquivo.setFileFilter(filter);          
          arquivo.setAcceptAllFileFilterUsed(false);  
          arquivo.setMultiSelectionEnabled(false);    
          File file = new File("user.dir");    
          int option = arquivo.showOpenDialog(this);
          PessoasDAO pDao = new PessoasDAO();
          if(option == JFileChooser.APPROVE_OPTION) {
              String caminhoArquivo = "";
              caminhoArquivo = arquivo.getSelectedFile().getAbsolutePath();
              file = arquivo.getSelectedFile();  
              String nomeArquivo = file.getName();  
              int e = nomeArquivo.lastIndexOf(".");  
              String extensao = nomeArquivo.substring(e);
              Image image = null;
              try {
                  image = ImageIO.read(file);
                   if(extensao.equalsIgnoreCase(".jpg")){
                        lblFoto.setIcon(new ImageIcon(arquivo.getSelectedFile().getAbsolutePath()));
                        lblNomeFoto.setText(caminhoArquivo);
                        lblFoto.setIcon(new ImageIcon(image.getScaledInstance(lblFoto.getWidth(),lblFoto.getHeight(), image.SCALE_DEFAULT)));  

                   }else{  
                         JOptionPane.showMessageDialog(null, "Arquivo não suportado", "Erro", JOptionPane.ERROR_MESSAGE);  
                    }      
              } catch (IOException ex) {
                  Logger.getLogger(CadPessoas.class.getName()).log(Level.SEVERE, null, ex);
              }
          }

Agora na hora de mostrar todos os dados do meu frame, eu preciso exibir a imagem que foi cadastrada junto a pessoa.
(Lembrando que no banco só está cadastrado na minha tabela Pessoa o caminho da minha imagem)
Se alguém puder ajudar eu agradeço…

Abraço e bons estudos a todos…

G

Alguem por favorrrrrrrr!!!

Estou entrando em crise já…
kkkkkkkkkk

Preciso carregar o conteudo desse caminho cadastrado no BD com hibernate, dentro de um jLabel.

G

Olá pessoal!
Segue abaixo o que eu fiz (quebrando a cabeça) e com a ajuda de alguns amigos, para copiar a imagem de um local (ex. Minhas Imagens) para um diretorio do meu sistema (Antes da pasta SRC).
OBS: Como já foi discutido várias vezes sobre salvar imagens no BD, minha sugestão para isso nao acontecer é fazer da seguinte forma:

1º - O Objeto (ex. Pessoa) ficaria sem ter o atributo para carregar imagens, logo, esse objeto ficaria da mesma maneira de um projeto que NÃO guarde as img no BD.
2º - Seu JFrame que faz o CRUD deveria ter la uma jLabel (ex. lblFoto) que iria setar a img para aparecer na aplicação.
3º - Eu criei um metodo utilizando JFileChooser para selecionar a imagem desejada. (esse metodo eu chamo no evento do meu botao de carregar imagem)

JFileChooser arquivo = new JFileChooser();  
          UIManager.put("FileChooser.openDialogTitleText", "Abrir");
          UIManager.put("FileChooser.lookInLabelText", "Consultar em");
          UIManager.put("FileChooser.openButtonText", "Abrir");
          UIManager.put("FileChooser.cancelButtonText", "Cancelar");
          UIManager.put("FileChooser.fileNameLabelText", "Nome do Arquivo");
          UIManager.put("FileChooser.filesOfTypeLabelText", "Tipo de Arquivo");
          UIManager.put("FileChooser.openButtonToolTipText", "Abrir o Arquivo Selecionado");
          UIManager.put("FileChooser.cancelButtonToolTipText","Cancelar");
          UIManager.put("FileChooser.fileNameHeaderText","Nome");
          UIManager.put("FileChooser.upFolderToolTipText", "Subir um Nível");
          UIManager.put("FileChooser.homeFolderToolTipText","Área de Trabalho");
          UIManager.put("FileChooser.newFolderToolTipText","Criar Nova Pasta");
          UIManager.put("FileChooser.listViewButtonToolTipText","Lista");
          UIManager.put("FileChooser.renameFileButtonText", "Renomear");
          UIManager.put("FileChooser.deleteFileButtonText", "Deletar");
          UIManager.put("FileChooser.filterLabelText", "Tipo");
          UIManager.put("FileChooser.detailsViewButtonToolTipText", "Detalhes");
          UIManager.put("FileChooser.fileSizeHeaderText","Tamanho");
          UIManager.put("FileChooser.fileDateHeaderText", "Data de Modificação");
          UIManager.put("FileChooser.acceptAllFileFilterText", "Todos os Arquivos");
          SwingUtilities.updateComponentTreeUI(arquivo);
          
          arquivo.setDialogTitle("Selecione a Imagem");    
          arquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);    
          FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG Images", new String[]{"jpg","png"});    
          arquivo.setFileFilter(filter);          
          arquivo.setAcceptAllFileFilterUsed(false);  
          arquivo.setMultiSelectionEnabled(false);    
          File file = new File("user.dir");    
          int option = arquivo.showOpenDialog(this);
          if(option == JFileChooser.APPROVE_OPTION) {
              String caminhoArquivo = "";
              caminhoArquivo = arquivo.getSelectedFile().getAbsolutePath();
              file = arquivo.getSelectedFile();  
              String nomeArquivo = file.getName();  
              int e = nomeArquivo.lastIndexOf(".");  
              String extensao = nomeArquivo.substring(e);
              Image image = null;
              try {
                  image = ImageIO.read(file);
              } catch (IOException ex) {
                  Logger.getLogger(CadPessoas.class.getName()).log(Level.SEVERE, null, ex);
              }
              if(extensao.equals(".jpg") || extensao.equals(".JPG")){
                    lblFoto.setIcon(new ImageIcon(arquivo.getSelectedFile().getAbsolutePath()));
                    try {
                        lblFoto.setIcon(new ImageIcon(arquivo.getSelectedFile().getCanonicalPath().replace("\\", "/")));
                    } catch (IOException ex) {
                        Logger.getLogger(CadPessoas.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    try {
                        caminhoArquivo = arquivo.getSelectedFile().getCanonicalPath().replace("\\", "/");
                    } catch (IOException ex) {
                        Logger.getLogger(CadPessoas.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    lblFoto.setIcon(new ImageIcon(image.getScaledInstance(lblFoto.getWidth(),lblFoto.getHeight(), image.SCALE_DEFAULT)));  
                    lblNomeFoto.setText(caminhoArquivo);
              }else{  
                  JOptionPane.showMessageDialog(null, "Arquivo não suportado", "Erro", JOptionPane.ERROR_MESSAGE);  
              }      
          }

4º - Para copiar a img para um diretorio do meu sistema eu faço assim:

ExecutarCmd exe = new ExecutarCmd(p.getPes_FotoNome(),"Imagens/"+p.getPes_Codigo()+".JPG");
exe.copiar();

5º - A minha classe ExecutarCmd:

public class ExecutarCmd {

	public static void copiarFile(String dirFonte, String dirDestino)
			throws IOException {

		File fonte = new File(dirFonte);
		File destino = new File(dirDestino);

		InputStream in = new FileInputStream(fonte);
		OutputStream out = new FileOutputStream(destino);

		byte[] buf = new byte[1024];
		int len;
		while ((len = in.read(buf)) > 0) {
			out.write(buf, 0, len);
		}
		in.close();
		out.close();
		System.out.println("copiado para o " + dirDestino);
	}

	public void executarComando(String dirPrograma) {
		try {
			Runtime.getRuntime().exec(dirPrograma);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void copiarArquivosDiretorios(String dirFonte, String dirDest) {
		if (!isExecucao()) {
			try {
				Runtime.getRuntime().exec(
						"xcopy " + dirFonte + "\\*.*  " + dirDest + " /S /Y");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public boolean isExecucao() {
		String s, saida = "";
		try {
			Process p = Runtime.getRuntime().exec("tasklist"); // aqui fica o
			// camando q
			// seleciona a
			// lista

			BufferedReader resultado = new BufferedReader(
					new InputStreamReader(p.getInputStream()));

			while ((s = resultado.readLine()) != null) {
				saida = saida + s;
				saida = saida + "\n";
			}

			int tOriginal = saida.toCharArray().length;
			saida = saida.substring(saida.indexOf("xcopy.exe"));

			if (tOriginal > saida.toCharArray().length) {
				System.out.println("ACHOU !!!!!!!");
				return true;
			} else {
				System.out.println("Nao ACHOU !!!!!!!");
				return false;
			}
		} catch (Exception ex) {
			System.out.println("Catch !!!!!!!: " + ex);
			return false;
		}
	}

	private String arquivoOrigem;
	private String arquivoDestino;

	/**
	 * Cria um objeto que recebe uma String com o nome do arquivo origem e outra
	 * String com o nome do arquivo destino.
	 * 
	 * @param arquivoOrigem
	 * @param arquivoDestino
	 */
	public ExecutarCmd(String arquivoOrigem, String arquivoDestino) {
		this.arquivoOrigem = arquivoOrigem;
		this.arquivoDestino = arquivoDestino;
	}

	/**
	 * Método que faz a cópia do arquivo origem lendo e gravando em blocos de
	 * 1024 bytes.
	 * 
	 * @throws IOException
	 */
	public void copiar() throws IOException {
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(
				arquivoOrigem));
		BufferedOutputStream out = new BufferedOutputStream(
				new FileOutputStream(arquivoDestino));
		byte[] buffer = new byte[1024];
		int qtdBytesLidos = in.read(buffer);
		while (qtdBytesLidos <= 1024) {
			out.write(buffer);
			qtdBytesLidos = in.read(buffer);
			if (qtdBytesLidos == -1)
				break;
		}
		in.close();
		out.close();
	}
}

6º - Para mostrar em uma jLabel essa minha img copiada eu faço assim:

ImageIcon img = new ImageIcon("imagens/"+pessoas.getPes_Codigo()+".JPG"); 
lblFoto.setIcon(new javax.swing.ImageIcon("imagens/"+pessoas.getPes_Codigo()+".JPG")); 
lblFoto.setIcon(new ImageIcon(img.getImage().getScaledInstance(lblFoto.getWidth(),lblFoto.getHeight(), Image.SCALE_DEFAULT)));

Bom, se alguém tiver alguma sugestão de melhoramento de código, ou sugestão de melhor processamento, etc. eu agradeço…
Espero ter ajudado!!!

Guilherme

J

Cara em tenho que fazer a mesma coisa que voce só que eu quero pegar o endereço jchooser enviar para uma pasta dentro do meu pacote dentro do java e madar pelo id que eu quando clicar em um do meus arquivos do banco apareça aa imagem atraves do id

B

Olá caro colega JEREMIAS souza lima
Tem 2 formas, armazena o path e grava o arquivo no diretório referente ao packager que quer, ou converte a imagem em binario e grava no banco e recupera no select e no seu metodo trata o binario para tornar a imagem novamente.
Quando precisei fiz da 2 forma e funciona.
RESOLVIDO

Criado 16 de março de 2012
Ultima resposta 14 de ago. de 2015
Respostas 10
Participantes 6