¡Esta es una revisión vieja del documento!
public void paint (java.awt.Graphics g)BufferedImage image = ImageIO.read (new ByteArrayInputStream (rawImageBytes));
ByteArrayOutputStream baos = new ByteArrayOutputStream( 1000 ); ImageIO.write( aBufferedImage, "jpeg", baos ); baos.flush(); byte[] resultImageAsRawBytes = baos.toByteArray(); baos.close();
BufferedImage image = ImageIO.read( new File( "rabbit.jpg" ) );
ImageIO.write( aBufferedImage, "jpeg", new File ("snap.jpg"));
BufferedImage bufferedImage = new BufferedImage ( imageWidth, imageHeight, BufferedImage.TYPE_INT_BGR ); bufferedImage.createGraphics().drawImage( image, 0, 0, this);
BufferedImage image = null; try { image = ImageIO.read( url ); } catch ( IOException e ) { System.out.println( "image missing" ); }
Métodos útiles:
Mediante esta clase podemos recopilar información del sistema de gráficos de la máquina donde se ejecuta el programa, para ello debemos coger el GraphicsEnvirontment local llamando al método getLocalGraphicsEnvirontment. Por ejemplo, para recoger las fuentes existentes en la máquina:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); for (String s : ge.getAvailableFontFamilyNames()) System.out.println(s);
Hola amigos!! Hoy vamos a asignar un color transparente para la imágen, para ello necesitamos:
Escogeremos el color que será el alpha y recorreremos la imágen pixel a pixel, si ese pixel es el color en cuestión le diremos que no tiene opacidad:
java.awt.Color colorAlpha = new Color(buffer.getRGB(0,0)); for (int i=0; i<buffer.getHeight(); i++) for (int j=0; j<buffer.getWidth(); j++) if (new Color(buffer.getRGB(j, i)).equals(colorAlpha)) buffer.setRGB(j,i,0&0&0&0);
Donde colorAlpha ha sido el color elegido (el que tiene el primer pixel de arriba a la izquierda) y buffer es la BufferImage.
Estilo de lápiz. Para usarla lo que hacemos es pasarle un objeto java.awt.BasicStroke. El primer parámetro de este es la anchura. Los siguientes son constantes estáticas de la clase BasicStroke, por ejemplo BasicStroke.CAP_ROUND redondearía los bordes. Un Stroke como el siguiente haría una línea discontinua:
float dash[] = {10.0f, 5.0f}; g2.setStroke (new BasicStroke (8.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
Estilo de relleno. Podemos usar distintos tipos de relleno, pasandole un objeto color nos crea un relleno plano, pero si le pasamos un objeto java.awt.GradientPaint podemos conseguir rellenos con degradados.
java.awt.GradientPaint redtowhite = new java.awt.GradientPaint (0,0,Color.RED,300,300,Color.WHITE); G.setPaint(redtowhite);
TexturePaint nos será útil para crear figuras rellenas con una BufferedImage como textura.
Estilo de composición de dibujos. Lo usamos para hacer operaciones con shapes ya dibujadas sobre el Graphics (unión, intersección…). Debemos usarla sobre el Graphics de un objeto BufferedImage.
Transformación de rotación, escala…
Restricción de dibujo. Una vez pasemos a este método del objeto Graphics una shape, todo lo dibujado quedará enmascarado por ese polígono.
Fuente que se usará.
Forma de renderizar.
El método setTransform aplica una transformación (escalado, traslación, rotación…) al objeto Graphics. Esta transformación se hace mediante el objeto AffineTransfrom, este tiene métodos para cada transformación permitida. Y una vez pasado al setTransform de un graphics todo lo que se dibuje sobre él a partir de entonces será transformado.
Si sólo queremos transformar una imágen tenemos dos formas de hacerlo:
Para hacer un espejo horizontal haremos un: scale(-1,1). Al método de escalado se le pasan dos doubles donde 1,1 es el tamaño actual, 0.5,0.5 la mitad… Si la aplicamos a todo el Graphics este se nos girará y probablemente no veamos parte de la pantalla.
Otra forma de aplicar las transformaciones es: nos quedamos con la transformación actual, creamos la nuestra y aplicamos nuestras acciones. Dibujamos. Y volvemos a aplicar la inicial:
AffineTransform origAT = g2d.getTransform( ); AffineTransform rot = new AffineTransform( ); rot.rotate( Math.toRadians(angle), img.getWidth( )/2, img.getHeight( )/2); g2d.transform(rot); g2d.drawImage(src, 0, 0, null); g2d.setTransform(origAT);
En esta clase encontramos métodos para dibujar elementos geométricos de forma avanzada. (Curvas, Puntos, Rectángulos (hasta con punta redondeada!! (RoundRectangle2D)), elipses…). Para dibujarlas llamamos al método draw del objeto Graphics2D, a él se le pasa una Shape (un objeto de los anteriores). Tengamos en cuenta que generalmente para hacer una nueva línea, rectángulo…. NO usaremos la clase Line2D Rectangle2D, sino una clase interna “Double” o “Float”: G.draw(new Line2D.Double(new Point2D.Double(0, 0), new Point2D.Double(400, 300)));
Rectangle rect1 = new Rectangle(20,50,100,100); Area a = new Area(rect1); Rectangle rect2 = new Rectangle(90,90,100,100); Area b = new Area(rect2); b.intersect(a); G.fill(b);
Podemos configurar el objeto de Graphics 2d para que al dibujo de texto no sea pixelado, sino suavizado:
... (Graphics g) if (g instanceof Graphics2D) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } g.drawString("Hola", 50, 100);
Para medir un texto usaremos la clase java.awt.FontMetrics, no podremos crear un objeto de esta clase mediante un constructor (ya que son protegidos), pero sí que podremos pedir a un objeto Graphics que nos devuelva el FontMetrics que tiene asociado, mediante el método getFontMetrics, y usarlo. Para que coja un string usaremos el método stringWidth, que ya te devuelve el ancho, y una vez con un string cogido podemos pedir el alto: getHeight.
El código siguiente te centra un String (str) en el frame:
FontMetrics met = G.getFontMetrics(); int w = met.stringWidth(str); int h = met.getHeight(); int xFin = (this.getWidth() / 2) - (w / 2); int yFin = (this.getHeight() / 2) - (h / 2); G.drawString(str, xFin,yFin);
Hemos de recordar que si cogemos el FontMetrics y luego cambiamos la fuente el FontMetrics del Graphics cambia pero el nuestro no (no debería ser una referencia???? ¿?¿?), por lo que lo tendríamos que volver a recoger.
Llegados a un punto, querremos hacer una pequeña animación, para ello podremos tener varias imágenes y las iríamos mostrando de una en una. Pero tal vez queramos organizarlo de otra forma y montar todas las imágenes en una y, cuando vayamos iniciemos el programa, este leerá la imágen grande y la convertirá en pequeñas. Para ello haremos lo siguiente:
El código siguiente llena el array de ImageBuffer (strip) que lee del BufferImagen orígen (img). Sabemos que una imágen pequeña tiene tamaño width\height. La imágen orígen son 6 imágenes (numImgs) pequeñas puestas en horizontal, sólo hay una fila de sprites:
for (int i=0; i < numImgs; i++) { strip[i] = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); Graphics g = strip[i].getGraphics(); g.drawImage(img, 0,0, width, height, width * i, 0, (width * i)+width, height, null); g.dispose(); }