2010-04-17 21 views
34

He marcado preguntas con nombres similares, pero no responden a este caso de uso.Usar Graphics2D para superponer texto en una imagen almacenada y devolver una imagen almacenada

Básicamente, debía superponer texto (texto) en una coordenada determinada (x, y) Tengo la siguiente función en un paquete;

protected BufferedImage Process2(BufferedImage image){ 
    Graphics2D gO = image.createGraphics(); 
    gO.setColor(Color.red); 
    gO.setFont(new Font("SansSerif", Font.BOLD, 12)); 
    gO.drawString(this.text, this.x, this.y); 
    System.err.println(this.text+this.x+this.y); 
    return image; 
} 

Siento que me falta algo obvio; cada referencia a Graphics2D que puedo encontrar es lidiar con cualquiera de los juegos o escribir directamente en un archivo, pero solo quiero que se devuelva una Imagen Buffered. con la superposición 'renderizada'

En el código actual, la imagen aparece sin cambios en el extremo.

Gracias!

+1

¿Estás tratando de modificar un archivo de imagen? Lo que hagas debería funcionar, pero solo estás modificando una representación en memoria de la imagen. – Guillaume

+1

Además, ¿está seguro de que xey están dentro de la imagen? Trate de pintar un cuadrado en coords (0,0) para una primera prueba – Guillaume

+1

Como un lado, esta es una vez que es apropiado llamar a'disponer() 'en la instancia' Graphics2D'. – trashgod

Respuesta

65

El método utiliza drawString()x y y por el carácter más a la izquierda de baseline. Los números generalmente no tienen descendientes; si lo mismo es cierto de text, una cadena dibujada en la posición (0,0) se representará completamente fuera de la imagen. Vea esto example.

Adición: Es posible que tenga problemas con un modelo de color incompatible en su imagen. Un recurso simple es renderizar la imagen y luego modificarla in situ.

Hello

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** 
* @see https://stackoverflow.com/questions/2658663 
*/ 
public class TextOverlay extends JPanel { 

    private BufferedImage image; 

    public TextOverlay() { 
     try { 
      image = ImageIO.read(new URL(
       "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png")); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     image = process(image); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(image.getWidth(), image.getHeight()); 
    } 

    private BufferedImage process(BufferedImage old) { 
     int w = old.getWidth()/3; 
     int h = old.getHeight()/3; 
     BufferedImage img = new BufferedImage(
      w, h, BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2d = img.createGraphics(); 
     g2d.drawImage(old, 0, 0, w, h, this); 
     g2d.setPaint(Color.red); 
     g2d.setFont(new Font("Serif", Font.BOLD, 20)); 
     String s = "Hello, world!"; 
     FontMetrics fm = g2d.getFontMetrics(); 
     int x = img.getWidth() - fm.stringWidth(s) - 5; 
     int y = fm.getHeight(); 
     g2d.drawString(s, x, y); 
     g2d.dispose(); 
     return img; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(image, 0, 0, null); 
    } 

    private static void create() { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new TextOverlay()); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       create(); 
      } 
     }); 
    } 
} 
+0

Bueno, para mis pruebas estoy usando x = image.getHeight()/2 y asimismo para y, así que no creo que ese sea el problema, ¡pero gracias! – Bolster

+0

¿Hay alguna posibilidad de que llame 'paintComponent()' con la imagen anterior en lugar de la nueva? – trashgod

+0

No estoy usando ningún JComponents así que no, no paintComponents; pero si me falta algo fundamental, por favor abrázame con él, no soy un codificador de GUI y tengo muy poco conocimiento sobre cómo manejar gráficos en Java, así que esto podría ser un enfoque completamente equivocado. – Bolster

Cuestiones relacionadas