Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat 7. Carregando e mostrando imagens locais Esta aula complementa os estudos de programação de interfaces gráficas em Java mostrando como podemos carregar imagens de arquivos locais ou da Internet para uso nos programas. A classe Image permite a criação de imagens gráficas a partir de arquivos que podem ser locais ou disponíveis na Internet. Os formatos de imagens reconhecidos mais usados são GIF e JPEG. Estas imagens podem ser mostradas facilmente em aplicações gráficas, como mostrado nos exemplos desta página. O programa abaixo exemplifica o uso da classe Image para carregar e mostrar uma imagem localizada em um arquivo. Exemplo 1. Um programa que demonstra uso da classe Image 1 /* Para podermos usar qualquer operação gráfica devemos incluir a linha abaixo */ 2 import java.awt.*; 3 /* Para podermos usar algumas operações relacionadas com a classe Image devemos incluir a linha abaixo */ 4 import java.awt.image.*; 5 6 /* Criamos uma classe que herda tudo da classe Canvas */ 7 class meuCanvas extends Canvas 8 { 9 /* A instância da classe Imagem deve ser visível de todos os métodos da classe meuCanvas */ 10 Image image = null; 11 meuCanvas() 12 { 13 /* Imagem é criada a partir do Toolkit relacionado com o Canvas - Claro que este programa 14 só vai funcionar se existir uma imagem chamada "compilando.gif" em um subdiretório 15 Images no diretório onde a classe está. */ 16 image = getToolkit().getImage("Images/compilando.gif"); 17 } 18 /* Método que pinta o canvas, simplesmente desenha a imagem */ 19 public void paint(Graphics g) 20 { 21 g.drawImage(image,0,0,this); 22 } 23 /* Este método é "mágico" - se existir, vai dar um tamanho preferido à instâncias 24 da classe meuCanvas, neste caso, o tamanho exato da imagem */ 25 public Dimension getPreferredSize() 26 { 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 1 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat return new Dimension(473,209); } } /* Criamos uma classe que herda tudo da classe Frame */ class minhaFrame extends Frame { minhaFrame(String título) // um construtor que recebe uma String como argumento { // chamo o construtor da classe Frame com o argumento título super(título); // Declaro e inicializo a instância da classe meuCanvas meuCanvas cv = new meuCanvas(); // adiciono a instância à classe Frame add(cv); // Peço à Frame que se ajuste pack(); // Digo que instâncias desta classe serão visíveis show(); } // fim do construtor para a classe minhaFrame } // fim da classe minhaFrame // uma classe que declara e usa uma instância da classe Frame class demoImage { public static void main(String args[]) { // Declaro uma nova instância da classe minhaFrame minhaFrame mf = new minhaFrame("Uma Imagem Local !"); } // fim do método main } // fim da classe Tratamento de imagens Para realizar o tratamento de imagens será utilizada a biblioteca JAI (Java Advanced Imaging). Neste documento serão apresentadas algumas funções para trabalhar com imagens. Exemplo 2. Programa simples para carregar imagens com o DisplayJAI, Fonte: http://www.lac.inpe.br/~rafael.santos/Java/JAI - 23/08/2005 package display; import import import import import java.awt.BorderLayout; java.awt.Container; javax.media.jai.JAI; javax.media.jai.PlanarImage; javax.swing.JFrame; 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 2 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat import javax.swing.JLabel; import javax.swing.JScrollPane; import com.sun.media.jai.widget.DisplayJAI; /** * Esta aplicação mostra como usar a classe DisplayJAI com um JScrollPane para mostrar as imagens */ public class DisplayJAIExample { public static void main(String[] args) { // carrega uma imagem que foi passada pela linha de comando PlanarImage image = JAI.create("fileload", args[0]); // Recolhe algumas informações da imagem String imageInfo = "Dimensions: "+image.getWidth() +"x"+image.getHeight()+ " Bands:"+image.getNumBands(); // Cria um frame para display. JFrame frame = new JFrame(); frame.setTitle("DisplayJAI: "+args[0]); // Recolhe o ContentPane do JFrame's. Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); // Cria uma instancia para o DisplayJAI. DisplayJAI dj = new DisplayJAI(image); // Add para o JFrame's ContentPane uma instancia de JScrollPane contendo a instancia do DisplayJAI. contentPane.add(new JScrollPane(dj),BorderLayout.CENTER); // Add um text label com informações da imagens. contentPane.add(new JLabel(imageInfo),BorderLayout.SOUTH); // Configura o botão fechar da janela para finalizar a aplicação. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400,400); // ajusta o tamanho do frame. frame.setVisible(true); // mostra o frame. } } Para trabalhar com os pixels é necessário utilizar as seguintes bibliotecas: import javax.media.jai.iterator.RandomIter; import javax.media.jai.iterator.RandomIterFactory; Exemplo 3. Veja um exemplo trabalhando com pixels import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.image.DataBuffer; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import javax.media.jai.iterator.RandomIter; import javax.media.jai.iterator.RandomIterFactory; import com.sun.media.jai.widget.DisplayJAI; import java.awt.BorderLayout; import java.awt.Container; 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 3 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import java.awt.image.SampleModel; /** * Esta classe mostra como pode extender a class DisplayJAI. Bem utilizando o método * mouseMoved do DisplayJAI então quando o mouse é movido, algumas informações * sobre o pixel que o mouse Aponte é armazenada (mas não mostrada). */ public class DisplayJAIWithPixelInfo extends DisplayJAI implements MouseMotionListener { private StringBuffer pixelInfo; // as informações do pixel (no formato StringBuffer). private double[] dpixel; // as informações do pixel como um array de doubles. private int[] ipixel; // as informações do pixel como um array de inteiros. private boolean isDoubleType; // indica qual dos arrays sera usado. private RandomIter readIterator; // RandomIter retorna os dados de um pixel simples private boolean isIndexed; // true if the image has a indexed color model. private short[][] lutData; // will contain the look-up table data if isIndexed is true. protected int width,height; // as dimensões da imagem /** * O construtor da classe, que cria os arrays e as instancias necessaries * para obter os dados e registros da imagem para listarem no movimento do mouse * @param imagem um RenderedImage para mostrar */ public DisplayJAIWithPixelInfo(RenderedImage image) { super(image); // chama o constructor para DisplayJAI. readIterator = RandomIterFactory.create(image, null); // cria o iterator. // Pega alguns dados sobre a imagem width = image.getWidth(); height = image.getHeight(); int dataType = image.getSampleModel().getDataType(); // pega o tipo do dado switch(dataType) { case DataBuffer.TYPE_BYTE: case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: case DataBuffer.TYPE_INT: isDoubleType = false; break; case DataBuffer.TYPE_FLOAT: case DataBuffer.TYPE_DOUBLE: isDoubleType = true; break; 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 4 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat } // Dependendo do tipo do dado da imagem, é alocado um double ou um int array. if (isDoubleType) dpixel = new double[image.getSampleModel().getNumBands()]; else ipixel = new int[image.getSampleModel().getNumBands()]; // Is the image color model indexed ? isIndexed = (image.getColorModel() instanceof IndexColorModel); if (isIndexed) { // Retrieve the index color model of the image. IndexColorModel icm = (IndexColorModel)image.getColorModel(); // Pega um numero de elementos em cada banda do mapa de cores int mapSize = icm.getMapSize(); // Aloca um array para guardar os dados da tabela byte[][] templutData = new byte[3][mapSize]; // Lê tabela armazenada de IndexColorModel. icm.getReds(templutData[0]); icm.getGreens(templutData[1]); icm.getBlues(templutData[2]); // carrega tabela armazenada dentro de um pequeno array lutData = new short[3][mapSize]; for(int entry=0;entry<mapSize;entry++) { lutData[0][entry] = templutData[0][entry] > 0 ? templutData[0][entry] : (short)(templutData[0][entry]+256); lutData[1][entry] = templutData[1][entry] > 0 ? templutData[1][entry] : (short)(templutData[1][entry]+256); lutData[2][entry] = templutData[2][entry] > 0 ? templutData[2][entry] : (short)(templutData[2][entry]+256); } } // end if indexed // Registra o movimento do mouse addMouseMotionListener(this); // Create the StringBuffer instance for the pixel information. pixelInfo = new StringBuffer(50); } /** * Este metodo é chamado quando o mouse é movido na imagem */ public void mouseMoved(MouseEvent me) { pixelInfo.setLength(0); // Limpa the StringBuffer int x = me.getX(); int y = me.getY(); if ((x >= width) || (y >= height)) { 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 5 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat pixelInfo.append("No data!"); return; } if (isDoubleType) // processa o pixel como um array de valores double { pixelInfo.append("(floating-point data) "); readIterator.getPixel(me.getX(),me.getY(),dpixel); // Lê o pixel for(int b=0;b<dpixel.length;b++) pixelInfo.append(dpixel[b]+","); // adiciona no StringBuffer pixelInfo = pixelInfo.deleteCharAt(pixelInfo.length()-1); // limpa última vírgula } else // Para os tipos de pixel não floating, serão processados como inteiros. { if (isIndexed) // if color model is indexed { pixelInfo.append("(integer data with colormap) "); readIterator.getPixel(me.getX(),me.getY(),ipixel); // Lê o pixel // Assume ipixel.length = 1 pixelInfo.append("Index: "+ipixel[0]); // Add também a entrada RGB dentro do LUT. pixelInfo.append(" RGB:"+lutData[0][ipixel[0]]+","+ lutData[1][ipixel[0]]+","+ lutData[2][ipixel[0]]); } else // pixels são do tipo inteiro, mas não indexed { //pixelInfo.append("(integer data) "); readIterator.getPixel(me.getX(),me.getY(),ipixel); // Lê o pixel for(int b=0;b<ipixel.length;b++) pixelInfo.append(ipixel[b]+","); // Adiciona no StringBuffer pixelInfo = pixelInfo.deleteCharAt(pixelInfo.length()-1); // Limpa última virgula } System.out.println(me.getX()+ ","+ me.getY()+","+pixelInfo);//+ pixel[band]); } // pixel is integer type } // end of method mouseMoved /** * This method allows external classes access to the pixel info which was * obtained in the mouseMoved method. * @return the pixel information, formatted as a string */ public String getPixelInfo() { return pixelInfo.toString(); } 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 6 Projeto V (U900005) – Ciências da Computação Projeto II (U900003) – Engenharia da Computação Prof. Valdir Gil Pillat } // end class class teste{ public static void main(String args[]){ PlanarImage image = JAI.create("fileload", "FBG_20020928193343.tif");//args[0]); String imageInfo = "Dimensions: "+image.getWidth()+"x"+image.getHeight()+ " Bands:"+image.getNumBands(); // Cria um frame para display. JFrame frame = new JFrame(); frame.setTitle("DisplayJAI: "+"FBG_20020928193343.tif");//args[0]); // Pega o JFrame's ContentPane. Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); // Cria uma instancia de DisplayJAI. DisplayJAIWithPixelInfo dj = new DisplayJAIWithPixelInfo(image); // Add para o JFrame's ContentPane uma instancia de JScrollPane contendo o // DisplayJAI instancia. contentPane.add(new JScrollPane(dj),BorderLayout.CENTER); // Add um text label com informações da imagem. contentPane.add(new JLabel(imageInfo),BorderLayout.SOUTH); // Configura a operação para finalizar a aplicação. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400,400); // ajusta o tamanho do frame. frame.setVisible(true); // mostra o frame.*/ } } Exercícios 1. Modifique o exemplo 3 para que o nome da imagem seja carregado do teclado. 2. No exemplo 3 procure o maior e o menor valor na intensidade dos pixels. 3. Selecione pedaços da imagem para analisar, como por exemplo um quadrado de 10x10 e indique quantos pontos fortes você encontra. 4. Modifique o exercício 3 para identificar os pontos fortes na imagem. 23/08/2005 http://www.fcc.univap.br/~valdir e-mail: [email protected] 7