Java-将文本写入图像,然后写入输出文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7745343/
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-10-30 21:14:42  来源:igfitidea点击:

Java- Write Text onto Image, then Write to Output File

javaimageswingtext

提问by TNC

I have an image on top of which I would like to write text that has multiple lines, is center-aligned, and dynamic (variable width). I've tried using the drawStringmethod from Graphics, but I could not get the centering and dynamic positioning to work. I'm currently poking around in the swinglibrary with JLabelsand such, but I'm having difficulty with finding a relatively simple approach to this. I would also like to have the final image written to a file, but it seems that mixing ImageIOwith JPanels is not working very well.. I'm getting just a black box at the moment.. If anyone could provide even a simple outline of how to approach this, I would greatly appreciate that.

我有一张图片,我想在上面写下多行、居中对齐和动态(可变宽度)的文本。我已尝试使用 中的drawString方法Graphics,但无法使居中和动态定位工作。我目前正在swing图书馆里闲逛JLabels,但我很难找到一种相对简单的方法来解决这个问题。我还想将最终图像写入文件,但似乎ImageIOJPanels混合效果不佳..我现在只是一个黑匣子..如果有人能提供一个简单的轮廓如何解决这个问题,我将不胜感激。

Thank you!

谢谢!



Sorry, I should have been more specific.. I would like the text itself to be center-aligned (as in the middle of each row should line up), rather than having the text be placed in the center of the image. The text will be placed in some other location on the image, not in the middle. Again, I apologize for the unclear descriptions. Thanks!

抱歉,我应该更具体。我希望文本本身居中对齐(因为每行的中间应该对齐),而不是将文本放置在图像的中心。文本将放置在图像的其他位置,而不是中间。再次,我为不清楚的描述道歉。谢谢!

回答by roartechs

You don't really need swing at all if you just want to generate image files.

如果您只想生成图像文件,则根本不需要swing。

You can do something like this:

你可以这样做:

import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.io.File;
import javax.imageio.ImageIO;
import java.io.IOException;

BufferedImage img = ImageIO.read(new File("dog.jpg")); // try/catch IOException
int width = img.getWidth();
int height = img.getHeight();

BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();

// draw graphics
g2d.drawImage(img, 0, 0, null);
g2d.drawString(text, x, y);

g2d.dispose();

try {

// Save as PNG
File file = new File("newimage.png");
ImageIO.write(bufferedImage, "png", file);

// Save as JPEG
file = new File("newimage.jpg");
ImageIO.write(bufferedImage, "jpg", file);

} catch (IOException e) { }

For more info, see:

有关更多信息,请参阅:

http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html

http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html

The text alignment and centering can be done using the FontMetrics class.

文本对齐和居中可以使用 FontMetrics 类来完成。

回答by Micha? ?rajer

You should use a drawString().

你应该使用一个drawString().

To properly center a text you need to calculate the width for a given font:

要正确居中文本,您需要计算给定字体的宽度:

Font font = getFont();
FontMetrics metrics = getFontMetrics( font );
int width = metrics.stringWidth( theString );

And remember to add -Djava.awt.headless=trueif you want to call in on server (without GUI).

-Djava.awt.headless=true如果您想在服务器上调用(没有 GUI),请记住添加。

回答by camickr

Use a JLabel to display the image and text:

使用 JLabel 显示图像和文本:

JLabel picture = new JLabel( new ImageIcon(...) );
picture.setText("<html><center>Text<br>over<br>Image<center></html>");
picture.setHorizontalTextPosition(JLabel.CENTER);
picture.setVerticalTextPosition(JLabel.CENTER);

Then you can use the Screen Imageclass to create an image of any component.

然后您可以使用Screen Image类来创建任何组件的图像。

Edit:

编辑:

Missed your update that you don't want the text centered on the image. For your new requirement you can add other components to the label to do the formatting for you. The code below shows the original suggestion as will as some examples of using components:

错过了您不希望文本以图像为中心的更新。对于您的新要求,您可以将其他组件添加到标签中,以便为您设置格式。下面的代码显示了原始建议以及使用组件的一些示例:

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