Java - 在图像中心绘制文本

6
我需要在图片中心写入文本,但要写入的文本并不总是相同的。

我正在使用以下代码:

// Here I first draw the image
g.drawImage(img, 22, 15, 280, 225, null);
// I get the text 
String text = photoText.getText();
// Set the text color to black
g.setColor(Color.black);
// I draw the string 
g.drawString(text, 79.5F, 220.0F);

问题在于文本不在图像中心,我应该怎么办?
我只需要将文本绘制在水平居中位置。
4个回答

7

使用JLabel会更加简单,但是可以使用FontMetrics直接管理几何形状,具体请参见这里


5
使用带有图标和文本的JLabel是最简单的方法。然后将水平/垂直文本位置设置为CENTER,文本将绘制在图像的中心。
从您的代码中看,您似乎正在尝试在图像底部附近绘制文本。在这种情况下,您可以使用带有图标的JLabel作为容器。然后,您可以将布局设置为类似于BoxLayout,并添加另一个带有文本的标签。
两种方法都不需要自定义绘画。
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class LabelImageText extends JPanel
{
    public LabelImageText()
    {
        JLabel label1 = new JLabel( new ColorIcon(Color.ORANGE, 100, 100) );
        label1.setText( "Easy Way" );
        label1.setHorizontalTextPosition(JLabel.CENTER);
        label1.setVerticalTextPosition(JLabel.CENTER);
        add( label1 );

        //

        JLabel label2 = new JLabel( new ColorIcon(Color.YELLOW, 200, 150) );
        label2.setLayout( new BoxLayout(label2, BoxLayout.Y_AXIS) );
        add( label2 );

        JLabel text = new JLabel( "More Control" );
        text.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        label2.add( Box.createVerticalGlue() );
        label2.add( text );
        label2.add( Box.createVerticalStrut(10) );

        //

        JLabel label3 = new JLabel( new ColorIcon(Color.GREEN, 200, 150) );
        add( label3 );

        JLabel text3 = new JLabel();
        text3.setText("<html><center>Text<br>over<br>Image<center></html>");
        text3.setLocation(20, 20);
        text3.setSize(text3.getPreferredSize());
        label3.add( text3 );

        //

        JLabel label4 = new JLabel( new ColorIcon(Color.CYAN, 200, 150) );
        add( label4 );

        JTextPane textPane = new JTextPane();
        textPane.setText("Add some text that will wrap at your preferred width");
        textPane.setEditable( false );
        textPane.setOpaque(false);
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        StyledDocument doc = textPane.getStyledDocument();
        doc.setParagraphAttributes(0, doc.getLength(), center, false);
        textPane.setBounds(20, 20, 75, 100);
        label4.add( textPane );
    }

    public static class ColorIcon implements Icon
    {
        private Color color;
        private int width;
        private int height;

        public ColorIcon(Color color, int width, int height)
        {
            this.color = color;
            this.width = width;
            this.height = height;
        }

        public int getIconWidth()
        {
            return width;
        }

        public int getIconHeight()
        {
            return height;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, width, height);
        }
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("LabelImageText");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new LabelImageText() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

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

我是指我需要在图像中心编写文本,然后保存图像。
您可以使用屏幕图像创建任何组件的图像。这假定您正在GUI上显示图像和文本。
或者,如果您只是想读取图像并将文本添加到图像中,然后保存图像,则需要创建BufferedImage,并在其上绘制图像,然后在其上绘制文本。您需要使用FontMetrics类,如Trashgod所提到的。我的建议无法帮助。

我将使用FontMetrics类,因为我需要保存图像,但我也在使用GUI,我可以使用您的建议吗? - GhzNcl
对于 ScreenImage,请点赞 +1;同时也可以参考这个 ImageIO 示例 - trashgod
@GhzNcl,我不明白你的问题。我给了你可用的代码。只有你自己能决定它是否符合你的要求。我还提供了一个ScreenImage的链接,展示如何在可见或不可见的组件上使用它。 - camickr

5

一种可能的解决方案:在JPanel中绘制图像,确保将面板的preferredsize设置为图像的大小,使用GridBagLayout设置面板,将文本放置在添加到JPanel中的JLabel中,不使用GridBagConstraints。这是将JLabel居中放置在JPanel中的一种方法。


我会尝试这种方式。谢谢。 - GhzNcl
但是用这种方法我无法保存图片,我的意思是如果我保存图片,文本将不会被保存。我正在寻找一种同时保存文本和图片的方法。我的意思是必须在图像中心编写文本,然后保存图像。 - GhzNcl

4
我使用TextLayout来使文本居中:

生成图像的示例

以下是创建图像并将其保存为文件的步骤:

int imgWidth = 250;
int imgHeight = 250;
var img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

Graphics2D g = img.createGraphics();

var backgroundColor = new Color(0, 150, 100);
g.setPaint(backgroundColor);
g.fillRect(0, 0, imgWidth, imgHeight);

var font = new Font("Arial", Font.PLAIN, 80);
g.setFont(font);
g.setPaint(Color.WHITE);

String text = "0";

var textLayout = new TextLayout(text, g.getFont(), g.getFontRenderContext());
double textHeight = textLayout.getBounds().getHeight();
double textWidth = textLayout.getBounds().getWidth();

g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

// Draw the text in the center of the image
g.drawString(text, imgWidth / 2 - (int) textWidth / 2,
                   imgHeight / 2 + (int) textHeight / 2);

String imgFormat = "png";
ImageIO.write(img, imgFormat, new File("/home/me/new_image." + imgFormat));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接