将文本装入 BufferedImage

Jay*_*Kay 3 java swing java-2d

我编写这个程序是为了找到一种方法,可以StringBufferedImage 任何大小(在本例中,a 的大小与其inBufferedImage相同JPanel)和位置上绘制居中的 a 。当我调整 的大小时JFrame,文本会在重新定位时闪烁BufferedImage,我不知道为什么。

import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
class test extends JPanel
{
    double scale = 0;
    String draw = "1";

test()
{
    setPreferredSize(new Dimension(600, 600));
}

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    paintText(g2, 0, 0);
}

public void paintText(Graphics2D g, int x, int y)
{   
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D big = (Graphics2D) bi.getGraphics();
    FontMetrics fm = big.getFontMetrics(); 

    scale = bi.getHeight()/(fm.getHeight());
    double xt = -(((scale*bi.getWidth())-bi.getWidth())/2);
    double yt = -(((scale*bi.getHeight())-bi.getHeight())/2);
    big.translate(xt, yt); 
    big.scale(scale, scale);
    big.drawString(draw, (bi.getWidth()/2)-(fm.stringWidth(draw)/2), (bi.getHeight()/2)+(fm.getHeight()/4)+1);
    g.drawImage(bi, x, y, this);
}

public static void main(String[] args)
{
    JFrame frame = new JFrame("test");
    frame.add(new test());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 5

主要问题是您尝试翻译并将文本居中BufferedImage,随着窗口大小的更改,计算会导致一定量的漂移,这意味着它们不会产生准确的位置。

经过一番折腾后,我基本上抛弃了你的BufferedImage方法setScale,并简单地根据该scale属性派生了一种新字体。

现在,您仍然可以生成BufferedImage,但我会使用结果FontMetrics来确定图像的实际大小,并简单地将图像渲染在帧的中心位置......但这就是我

缩放字体

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.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class Test101 extends JPanel {

    double scale = 0;
    String draw = "1";

    Test101() {
        setPreferredSize(new Dimension(600, 600));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        paintText(g2, 0, 0);

        int x = getWidth() / 2;
        int y = getHeight() / 2;
        g2.setColor(Color.RED);
        g2.drawLine(x, 0, x, getHeight());
        g2.drawLine(0, y, getWidth(), y);
    }

    public void paintText(Graphics2D g, int x, int y) {
        
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        
        FontMetrics fm = g.getFontMetrics();
        System.out.println(fm.getAscent());
        scale = getHeight() / (fm.getHeight());
        
        Font font = g.getFont().deriveFont(Font.PLAIN, AffineTransform.getScaleInstance(scale, scale));
        g2d.setFont(font);
        g2d.setColor(Color.WHITE);
        fm = g.getFontMetrics(font);
        int xPos = (getWidth() - fm.stringWidth(draw)) / 2;
        int yPos = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
        g2d.drawString(draw, xPos, yPos);
        g2d.dispose();
        
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("test");
                frame.add(new Test101());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)