Graficación UNIDAD II.- TRANSFORMACIONES GEOMÉTRICAS ___________________________________________________________________ LECCIÓN 2.5 Transformaciones de la composición general y de eficiencia computacional. ___________________________________________________________________ 2.5.1.- Procesamiento de Imágenes Una imagen digital es una representación rasterizada de una imagen en 2D definida como un arreglo de puntos (pixeles). AWT – Una imagesn es representada por la clase Image. – Se utiliza el modelo de empuje para imágenes. – AWT utiliza dos objetos: Productor y Consumidor (ImageProducer e ImageConsumer). Un productor actua como el origen de una imagen y el consumidor la recibe para presentarlas en un dispositivo rasterizador. Java2D – Una imagen es representada por la clase BufferedImage – Se utiliza el modelo inmediato. – Un BufferedImage contiene un Raster y un ColorModel. Carga de imagenes en Java2D – Para leer una imagen de un archivo: BufferedImage bi = ImageIO.read(file); Rafael Rivera López 1 Graficación – Una imagen puede ser manipulada utilizando operaciones de procesamiento de imágenes Para las siguientes operaciones: – f(x,y) representa un pixel de la imagen original – g(x,y) representa el pixel de la imagen resultante RescaleOp Ejecuta un ecalado pixel por pixel. g(x, y) = af(x, y) + b ColorConverOp Ejecuta una conversión de colores. LookupOp Ejecuta una conversión de pixeles basado en una tabla de búsqueda g(x, y) = T(f(x, y)) Rafael Rivera López 2 Graficación AffineTransformOp Ejecuta una transformación afin sobre la imagen: g(x, y) = f(A(x, y)) ConvolveOp – Define una operación de convolución. – Una convolución es una transformación lineal: – Para imágenes digitales: – K es una función denominada el Kernel. – K es una matriz en imágenes digitales – El Kernel define efectos como suavizado, nitidez, y detección de bordes. Métodos: dst = op.filter(src, null); Para aplicar una operación sobre una imagen: g.drawImage(bi, 0, 0, this); Para presentar una imagen ImageIO.write(bi, type, file); Para guardar una imagen bi: Es el objeto a guardado. type: Es un String indicando el formato file: es el archivo a crear Rafael Rivera López 3 Graficación package procimagenes; import import import import import import import import javax.swing.*; java.awt.event.*; java.awt.*; java.awt.color.*; java.awt.geom.*; java.awt.image.*; java.io.*; javax.imageio.*; public class Ventana extends JFrame implements ActionListener{ private JMenuItem mOpen; private JMenuItem mAWT; private JMenuItem mSave; private JMenuItem mExit; private JMenuItem mCopy; private JMenuItem mSmooth; private JMenuItem mSharpen; private JMenuItem mEdge; private JMenuItem mRescale; private JMenuItem mRotate; private JMenuItem mGray; private ImagePanel imageSrc; private ImagePanel imageDst; private JFileChooser fc = new JFileChooser(); public Ventana(){ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addMenu(); addComponentes(); addEventos(); pack(); setVisible(true); } public void addComponentes(){ Container cp = this.getContentPane(); cp.setLayout(new FlowLayout()); imageSrc = new ImagePanel(); imageDst = new ImagePanel(); cp.add(imageSrc); cp.add(imageDst); } Rafael Rivera López 4 Graficación public void addMenu(){ JMenuBar mb = new JMenuBar(); setJMenuBar(mb); JMenu menu1 = new JMenu("Archivo"); JMenu menu2 = new JMenu("Proceso"); mOpen = new JMenuItem("Abrir"); mAWT = new JMenuItem("Abrir (awt)"); mSave = new JMenuItem("Guardar"); mExit = new JMenuItem("Salir"); mCopy = new JMenuItem("Copiar"); mSmooth = new JMenuItem("Suavizar"); mSharpen = new JMenuItem("Nitidez"); mEdge = new JMenuItem("Orillas"); mRescale = new JMenuItem("Reescalar"); mRotate = new JMenuItem("Girar"); mGray = new JMenuItem("Escala de Grises"); menu1.add(mOpen); menu1.add(mAWT); menu1.add(mSave); menu1.addSeparator(); menu1.add(mExit); menu2.add(mCopy); menu2.add(mSmooth); menu2.add(mSharpen); menu2.add(mEdge); menu2.add(mRescale); menu2.add(mRotate); menu2.add(mGray); } mb.add(menu1); mb.add(menu2); public void addEventos(){ mOpen.addActionListener(this); mAWT.addActionListener(this); mSave.addActionListener(this); mExit.addActionListener(this); mCopy.addActionListener(this); mSmooth.addActionListener(this); mSharpen.addActionListener(this); mEdge.addActionListener(this); mRescale.addActionListener(this); Rafael Rivera López 5 Graficación } mRotate.addActionListener(this); mGray.addActionListener(this); public void actionPerformed(ActionEvent ev) { String cmd = ev.getActionCommand(); if ("Abrir".equals(cmd)) { int retval = fc.showOpenDialog(this); if (retval == JFileChooser.APPROVE_OPTION) { try { BufferedImage bi = ImageIO.read(fc.getSelectedFile()); imageSrc.setImage(bi); pack(); } catch (IOException ex) { ex.printStackTrace(); } } } else if ("Abrir (awt)".equals(cmd)) { int retval = fc.showOpenDialog(this); if (retval == JFileChooser.APPROVE_OPTION) { Toolkit tk = Toolkit.getDefaultToolkit(); Image img = tk.getImage(fc.getSelectedFile().getPath()); MediaTracker tracker = new MediaTracker(new Component() {}); tracker.addImage(img, 0); try { tracker.waitForID(0); } catch (InterruptedException ex) {} BufferedImage bi = new BufferedImage(img.getWidth(this), img.getHeight(this), BufferedImage.TYPE_INT_RGB); bi.getGraphics().drawImage(img, 0, 0, this); imageSrc.setImage(bi); } } else if ("Guardar".equals(cmd)) { int retval = fc.showSaveDialog(this); if (retval == JFileChooser.APPROVE_OPTION) { try{ ImageIO.write(imageDst.getImage(), "png",fc.getSelectedFile()); } catch (IOException ex) { ex.printStackTrace(); } } } else if ("Salir".equals(cmd)) { System.exit(0); } else if ("Copiar".equals(cmd)) { imageSrc.setImage(imageDst.getImage()); Rafael Rivera López 6 Graficación } else { procesarImagen(cmd); } } } public void procesarImagen(String opName){ BufferedImageOp op = null; System.out.println(opName); if (opName.equals("Suavizar")) { float[] data = new float[9]; for (int i = 0; i < 9; i++) data[i] = 1.0f/9.0f; Kernel ker = new Kernel(3,3,data); op = new ConvolveOp(ker); } else if (opName.equals("Nitidez")) { float[] data = {0f, -1f, 0f, -1f, 5f, -1f, 0f, -1f, 0f}; Kernel ker = new Kernel(3,3,data); op = new ConvolveOp(ker); } else if (opName.equals("Orillas")) { float[] data = {0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f}; Kernel ker = new Kernel(3,3,data); op = new ConvolveOp(ker); } else if (opName.equals("Reescalar")) { op = new RescaleOp(1.5f, 1.5f, null); } else if (opName.equals("Escala de Grises")) { op = new ColorConvertOp( ColorSpace.getInstance(ColorSpace.CS_GRAY), null); } else if (opName.equals("Girar")) { AffineTransform xform = new AffineTransform(); xform.setToRotation(Math.PI/6); op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR); } BufferedImage bi = op.filter(imageSrc.getImage(), null); imageDst.setImage(bi); pack(); } class ImagePanel extends JPanel{ BufferedImage image = null; public ImagePanel() { image = null; Rafael Rivera López 7 Graficación setPreferredSize(new Dimension(256, 256)); } public ImagePanel(BufferedImage bi) { image = bi; } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D)g; if (image != null) g2.drawImage(image, 0, 0, this); else g2.drawRect(0, 0, getWidth()-1, getHeight()-1); } public BufferedImage getImage() { return image; } public void setImage(BufferedImage bi) { image = bi; setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight())); invalidate(); repaint(); } } Rafael Rivera López 8