web-dev-qa-db-fra.com

Utilisation de Graphics2D pour superposer du texte sur une BufferedImage et renvoyer une BufferedImage

J'ai vérifié des questions portant le même nom, mais elles ne répondent pas à ce cas d'utilisation.

Fondamentalement, je devais superposer du texte (texte) à une coordonnée donnée (x, y) J'ai la fonction ci-dessous dans un package;

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;
}

J'ai l'impression de rater quelque chose d'évident; chaque référence à Graphics2D que je peux trouver concerne des jeux ou écrit directement dans un fichier, mais je veux juste qu'un BufferedImage soit renvoyé. avec la superposition "rendue"

Dans le code actuel, l'image apparaît inchangée à la fin.

Merci!

39
Bolster

La méthode drawString() utilise x et y pour le caractère le plus à gauche ligne de base . Les nombres n'ont généralement pas de descendants; si c'est la même chose pour text, une chaîne dessinée à la position (0,0) sera rendue entièrement en dehors de l'image. Voir ceci exemple .

Addendum: vous rencontrez peut-être des problèmes avec un modèle de couleur incompatible dans votre image. Un moyen simple consiste à rendre l'image puis à la modifier 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();
            }
        });
    }
}
70
trashgod