Desenhando imagens

Olá…Estou estudando a API gráfica do Java. Para compreender os conceitos envolvidos estou desenvolvendo pequenas aplicações…

Estou neste momento querendo estudar melhor a BufferedImage. Assim, desenvolvi uma aplicação que recebe um diretório de imagens jpg como parâmetro e gera uma imagem resultante que é uma espécie de mosaico de fragmentos de imagens contidas neste diretório…Em outras palavras, a aplicação fica recortando sub-imagens das imagens do diretório parâmetro e colando na imagem resultante…

Eu havia conseguido bons resultados (esou enviando um exemplo em anexo), todavia buscando fazer alguns ajustes no código, fiz alguma alteração (da qual não me recordo) e a partir dai a coisa não funcionou mais como deveria…

Segue meu código atual:

package colador;

import java.io.File;
import java.util.ArrayList;
import java.awt.image.BufferedImage;
import java.awt.Color;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.Dimension;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Random;
import java.awt.geom.Ellipse2D.Float;
import java.awt.Graphics2D;

public class FazColagens1
{
    private File[] arquivosDeImagem;
    private ArrayList<File> imagensParaUsar;
    private BufferedImage imagemResultante;
    private Graphics2D contextoGrafico;
    private Random geraNumero;
    
    public FazColagens1()
    {
        this.arquivosDeImagem = null;	
        this.imagemResultante = null;	
        this.imagensParaUsar = null;
        this.geraNumero = new Random();
    }
    
    public void inicializaColador(File diretorioDeImagens)throws Exception
    {
         if(diretorioDeImagens.isDirectory())
         {
            File[] arquivos = getArquivosDeImagem(diretorioDeImagens);
            if(arquivos.length>0)
            {
                this.arquivosDeImagem = arquivos;
                this.imagensParaUsar = new ArrayList(Arrays.asList(this.arquivosDeImagem));
                
                Dimension dimensaoDaImagemFinal = getDimensaoDaImagem();
                
                this.imagemResultante = new BufferedImage((int)dimensaoDaImagemFinal.getWidth(),
                                                          (int)dimensaoDaImagemFinal.getHeight(),
                                                          BufferedImage.TYPE_INT_RGB);
                
                this.contextoGrafico = this.imagemResultante.createGraphics();
                
                this.contextoGrafico.setColor(Color.black);
                this.contextoGrafico.drawRect(0, 0, imagemResultante.getWidth(), imagemResultante.getHeight()); 
                
                this.contextoGrafico.setPaintMode();
                this.contextoGrafico.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
                this.contextoGrafico.setComposite(java.awt.AlphaComposite.getInstance(java.awt.AlphaComposite.SRC_OVER, 0.2f)); 
            }
            else
            {
                throw new Exception();
            }
         }
         else
         {
            throw new Exception();
         }
    }
    
    public File[] getArquivosDeImagem(File diretorioDeImagens)
    {
        ArrayList<File> arquivos = new ArrayList();

        File[] filhos = diretorioDeImagens.listFiles();

        for(int i=0;i<filhos.length;i++)
        {
            if( (filhos[i].getName()).endsWith("jpg") ||  (filhos[i].getName()).endsWith("jpeg"))
            {
                arquivos.add(filhos[i]);
            }
        }

        filhos = new File[arquivos.size()];

        for(int i=0;i<arquivos.size();i++)
        {
            filhos[i] = arquivos.get(i);
        }

        return filhos;
    }
    
    public Dimension getDimensaoDaImagem()
    {
        BufferedImage imagem;

        int larguraMax = 0, alturaMax=0;
        //long tempoInicial = System.currentTimeMillis(),tempoFinal = 0;
        for(int i=0;i<arquivosDeImagem.length;i++)
        {
                //System.out.println("imagem "+i+" de "+arquivosDeImagem.length+" ");
            try
            {
                imagem = ImageIO.read(arquivosDeImagem[i]);

                if(imagem.getWidth()>larguraMax)
                {
                    larguraMax = imagem.getWidth();
                }

                if(imagem.getHeight()>alturaMax)
                {
                    alturaMax = imagem.getHeight();
                }
            }
            catch(Exception ex){}
        }
        //tempoFinal = System.currentTimeMillis();
        //System.out.println(""+((tempoFinal-tempoInicial)/arquivosDeImagem.length)+" milissegundos por imagem");
        //System.out.println("["+larguraMax+","+alturaMax+"]");
        return new Dimension(larguraMax,alturaMax);
    }
    
    private BufferedImage getImagemAtual()throws IOException
    {
        if(this.imagensParaUsar.isEmpty())
        {
            this.imagensParaUsar = new ArrayList(Arrays.asList(this.arquivosDeImagem));
        }
        File arquivo = this.imagensParaUsar.remove( this.geraNumero.nextInt( this.imagensParaUsar.size() ) );
        return ImageIO.read(arquivo);
    }
    
    public void recortaEColaRetangulo(int largura, int altura)throws Exception
    {
        BufferedImage imagemAtual = getImagemAtual();

        int posX = this.geraNumero.nextInt(imagemAtual.getWidth());
        int posY = this.geraNumero.nextInt(imagemAtual.getHeight());
        
        
        if((posX+largura)>imagemAtual.getWidth())
        {
            /*Se a área de recorte extrapolar a área da figura no eixo X,
             a posicao inicial de recorte em X é ajustada de forma que
             a área de recorte fique totalmente dentro da área da figura*/
            posX = posX-((posX+largura)-imagemAtual.getWidth());
        }
        
        if((posY+altura)>imagemAtual.getHeight())
        {
            /*Se a área de recorte extrapolar a área da figura no eixo Y,
             a posicao inicial de recorte em Y é ajustada de forma que
             a área de recorte fique totalmente dentro da área da figura*/
            posY = posY-((posY+altura)-imagemAtual.getHeight());
        }
        
        //obtém um sub-imagem da imagem atual
        imagemAtual = imagemAtual.getSubimage(posX, posY, largura, altura);
        
        posX = this.geraNumero.nextInt(this.imagemResultante.getWidth());
        posY = this.geraNumero.nextInt(this.imagemResultante.getHeight());
        
        
        if((posX+largura)>this.imagemResultante.getWidth())
        {
            //Processo análogo ao anterior, só que para a colagem
            posX = posX-((posX+largura)-this.imagemResultante.getWidth());
        }
        
        if((posY+altura)>this.imagemResultante.getHeight())
        {
            //Processo análogo ao anterior, só que para a colagem
            posY = posY-((posY+altura)-this.imagemResultante.getHeight());
        }

        //A sub-imagem é "colada" na imagem resultante
        this.contextoGrafico.drawImage(imagemAtual,posX,posY,null);
        this.contextoGrafico.dispose();
    }
    
    public BufferedImage getImagemResultante()
    {
        return this.imagemResultante;
    }
    
    public static void main(String[] parametros)
    {
        try
        {
            FazColagens fazColagens = new FazColagens();
            File diretorioDeImagens = new File("C:\\Joel Luis Carbonera\\Imagens\\Fotos\\Diversas\\");
            //File diretorioDeImagens = new File(parametros[0]);
            fazColagens.inicializaColador(diretorioDeImagens);
            
            Random geraNumero = new Random();
            
            for(int i=0;i<500;i++)
            {
                System.out.println("Colando "+i+"");
                try
                {
                    fazColagens.recortaEColaRetangulo(geraNumero.nextInt(200), geraNumero.nextInt(200));
                    System.out.println("\t"+i+" colado");
                }
                catch(Exception ex)
                {
                    //ex.printStackTrace();
                }
            }
            
            try
            {
                ImageIO.write(fazColagens.getImagemResultante(), "jpg", new File("resultado.jpg"));
                System.out.println("Gravado");
            }
            catch(Exception ex){ex.printStackTrace();}
        }
        catch(Exception ex){ex.printStackTrace();}
    }
}

Eu executo este código só que, na imagem resultante, parece que minha aplicação só desenha o último fragmento de imagem…Não sei o que fiz de errado…


Então eclipso o problema é que você tá dando um dispose a cada iteração. Depois de um dispose, qualquer cois que tu faz é ignorada no graphics. Comente o dispose da linha 178.

Cara…Pior que eu tirei essa linha e o problema persistiu. Só é desenhada a última sub-imagem extraída…

Em relação ao dispose(). Se eu chamá-lo, só conseguirei desenhar novamente na imagem se criar outro contexto gráfico com o createGraphics()?

Sim, de acordo com a especificação da API [quote]Disposes of this graphics context and releases any system resources that it is using. A Graphics object cannot be used after disposehas been called.[/quote]

Eu peguei o teu código, tirei o dispose e funcionou, bizarro. :shock:

Funcionou como? Gerou uma imagem parecida com o meu anexo?

Isso mesmo, como no exemplo do primeiro post.

Cara…Não sei como, agora voltou a funcionar…Aparentemente “do nada”. Deve ter sido alguma confusão com o netbeans. Talvez ele tenha mantido a class antiga, sem legar em consideração minhas modificações. Mas é especulação, é claro…