[RESOLVIDO] Retirar a imagem (byte[]) do banco e setar em um JLabel!

Olá gostaria que alguem me ajudasse pois já pesquisei bastante mas não encontrei uma boa solução. O problema é o seguinte:

Estou salvando uma imagem no postgres através de uma aplicação:

//Capturo essa foto através de um FileChooser que me retorna um BufferedImage com o nome image dai faço o seguinte:

//Logo apos salvo no Postgres assim:

O problema é na hora de setar em um JLabel não mostra nada:

//Setando o JLabel com o byte[] retirado do banco:

//Dai não mostra nada no JLabel…ja realizei testes pra ver se o byte[] retornado do banco estava vazio, mas está tudo ok.

Gostaria da ajuda de vcs com links, dicas ou outros meios meios pra que eu possa estar solucionando este problema.

Agradeço desde já.

Acontece que o array de byte gravado é só o DataBuffer da imagem (seu conteúdo). O construtor de ImageIcon só aceita um array de byte de todo o arquivo (incluindo informações sobre seu formato).

Para criar um Image, você precisará fazer exatamente o processo contrário da gravação:

  1. Crie um DataBufferByte a partir do array lido do banco.
  2. Crie um SampleModel (o tipo específico dependerá da sua necessidade).
  3. Crie um Raster (Raster.createRaster) a partir desses dois objetos que você criou anteriormente.
  4. Crie um BufferedImage com a altura e largura apropriados (a partir das dimensões do Raster).
  5. Defina o Raster do BufferedImage como sendo aquele que você criou (BufferedImage.setData).
  6. Crie um ImageIcon a partir do BufferedImage.

Ufa! Perceba que nesse procedimento você vai do nível mais baixo (array de bytes) até o mais alto (um componente que exibe a imagem renderizada), que é justamente o oposto do que você vez ao gravar a imagem no banco.

Tentei desta maneira:

[code] if (foto != null) {
BufferedImage img = null;

        try {
            img = ImageIO.read(new ByteArrayInputStream(foto));
            SampleModel a = img.getSampleModel();


            Raster raster = Raster.createRaster(a, img.getData().getDataBuffer(), null);
            BufferedImage buffer = null;
            buffer = buffer.getSubimage(raster.getMinX(), raster.getMinY(), raster.getWidth(), raster.getHeight());
            buffer.setData(raster);
            this.jLabelFoto.setIcon(new ImageIcon(buffer));

        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Erro ao converter o vetor " +
                    "de Bytes[] em BufferedImage" + e.getMessage());
            e.printStackTrace();
        }[/code]

Deu erro na criação do SampleModel, alguma dica?

Assim como o construtor de ImageIcon, o ImageIO.read só funciona corretamente se o conteúdo do InputStream for uma imagem em um formato específico (não basta passar o bytes somente da imagem - um mapa de bits, no caso de imagens bitmap).

Tente seguir o procedimento que eu te informei acima.

Marcos tem como vc me dar um exemplo para criar um SampleModel (ou algum link, tutorial, etc). A extensão da imagem não importa pra mim, a única utilização será pra vizualizar na aplicação.

Agradeço pela ajuda desde já!

Segundo a documentação da classe SampleModel:

“All image data is expressed as a collection of pixels. Each pixel consists of a number of samples. A sample is a datum for one band of an image and a band consists of all samples of a particular type in an image. For example, a pixel might contain three samples representing its red, green and blue components.”

Procure por subclasses concretas de SampleModel.

Afff to aqui ainda cara tentando mais ainda não consegui…

Você deve criar um Input ou um Output stream no banco. E usar o método ImageIO.write ou ImageIO.read sobre ele. Não esqueça de criar uma coluna para gravar o nome do formato de arquivo também.

Dificilmente você vai trabalhar com o array d ebytes diretamente. Não é prático, nem rápido, nem inteligente.

Aqui tem um exemplo: http://www.guj.com.br/posts/list/136313.java#739279

Vlw !!! Vou testar o código e depois posto o resultado!!! :stuck_out_tongue:

Olá testei durante esses dias mas não consegui resolver meu problema…estou fazendo exatamente como passado mas sempre gera esse erro:

org.postgresql.jdbc3.Jdbc3PreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V

Estou realizando os teste desta maneira:

No postgres o domínio foto está como bytea.

[code]
public boolean adicionarFoto(String caminho) {

    File imgFile = new File(caminho);
   
    BufferedInputStream imagem = new BufferedInputStream(new FileInputStream(imgFile));
        
    addFoto.setBinaryStream(1,imagem, imgFile.length());[/code]

Já pedi ajuda aos meus colegas e professores da faculdade, mas eles salvam a imagem em um arquivo temporário.

Estava precisando consertar isso hoje, pois amanhã meus professores pediram pra mostrar meu projeto de biometria para os alunos novatos da faculdade!!!

Grato!!!

Aee galera consegui vou ajeitar o código e postar ae. Com certeza vai servir pra muita gente.

Segue o código de manipulação com a imagem:

Colocando no banco :

public void adicionarFoto(String path)  {
        BufferedInputStream imagem = null;

        File imgFile = new File(path);
        
        try {
            
             imagem = new BufferedInputStream(new FileInputStream(imgFile));
this.addFoto.setBinaryStream(1,imagem, imagem.available());
            this.addFoto.executeUpdate();

        } catch (FileNotFoundException ex) {
            Logger.getLogger(SQL.class.getName()).log(Level.SEVERE, null, ex);
        } } catch (SQLException ex) {
            Logger.getLogger(SQL.class.getName()).log(Level.SEVERE, null, ex);
        }
       
    }

Montando uma imagemIcon apartir de uma imagem no banco.

[code]
public void selecioneFoto(){
Image imagem = null;
try {
ResultSet rs= this.selectFoto.executeQuery();

if (rs.next())

      imagem = Toolkit.getDefaultToolkit().createImage(rs.getBytes("foto"));
    } catch (SQLException ex) {
        Logger.getLogger(SQL.class.getName()).log(Level.SEVERE, null, ex);
    }
    new ImageIcon(imagem);
}[/code]

Não sei para que você precisa transformar, mas pode usar um ByteArrayInputStream:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/ByteArrayInputStream.html

Ué… se você já sabe que classe usar, é só usá-la. Crie um BufferedInputStream passando o array de bytes para o construtor de depois leia a imagem com ImageIO (passando o BufferedInputStream criado).

Pois é cara tava dando maior desastre aqui ao fazer isso. Tem coisas que não da pra explicar ex:

public static void main(String[] args) { JOptionPane.showMessageDialog(null, "dfdf", "qw", JOptionPane.OK_OPTION); JOptionPane.showMessageDialog(null, "dfdf", "qw", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(null, "dfdf", "qw", JOptionPane.ERROR_MESSAGE); }
Logo vai perceber que as imagens retornadas estão todas erradas.

“Coisas simples as vezes se tornam difíceis!”

Já dei um jeito no que eu queria: a classe que tem o atributo foto coloquei como Object, logo apos criei uma classe pra manipular e fazer as criações de imagem de acordo com o dado passado (BufferedInputStream e byte[]).

Quero aqui agradecer ao Marcos e ao ViniGodoy pela ajuda, espero poder ajudar muita gente aqui no guj tambem.

Meus Agradecimentos!!!