Java 使用 Graphics2D 在 BufferedImage 上叠加文本并返回 BufferedImage

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2658554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:26:39  来源:igfitidea点击:

Using Graphics2D to overlay text on a BufferedImage and return a BufferedImage

javabufferedimagegraphics2d

提问by Bolster

I have checked similarly named questions, but they don't answer this use case.

我检查了类似命名的问题,但他们没有回答这个用例。

Basically, I was to overlay some text (text) at a given coordinate (x,y) I have the below function in a package;

基本上,我是在给定的坐标 (x,y) 上覆盖一些文本 (text) 我在包中有以下功能;

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

I feel like im missing something patently obvious; every reference to Graphics2D I can find is dealing with either games or writing directly to a file but I just want a BufferedImage returned. with the overlay 'rendered'

我觉得我错过了一些显而易见的东西;我能找到的每个对 Graphics2D 的引用都是处理游戏或直接写入文件,但我只想返回一个 BufferedImage 。叠加“渲染”

In the current code, the image appears out the end unchanged.

在当前代码中,图像出现在末尾不变。

Thanks!

谢谢!

采纳答案by trashgod

The method drawString()uses xand yfor the leftmost character's baseline. Numbers typically have no descenders; if the same is true of text, a string drawn at position (0,0) will be rendered entirely outside the image. See this example.

该方法drawString()使用xy作为最左边字符的基线。数字通常没有降序;如果 也是如此text,则在位置 (0,0) 绘制的字符串将完全呈现在图像之外。请参阅此示例

Addendum: You may be having trouble with an incompatible color model in your image. One simple expedient is to render the image and then modify it 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();
            }
        });
    }
}