创建具有未知尺寸的BufferedImage

时间:2014-09-23 10:24:42

标签: java swing fonts font-size bufferedimage

我有一个扩展BufferedImage的类,它应该显示为提供给它的构造函数的字符串。我希望这样做的原因是允许graphics2D的抗锯齿功能(有关详细信息,请参阅我的previous question,如果您有任何更好的建议,请务必建议它们!)。我现在有BufferedImage类工作,但我无法弄清楚如何确定所需的宽度和高度,以便在实际设置字体之前显示输入字符串。一旦设置了初始大小,我也找不到调整BufferedImage父级大小的方法。这是我的代码:

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

public class Test extends JFrame{
    public Test(){
        this.add(new JLabel(new ImageIcon(new IconImage("Test", new Font("Sans-Serif", Font.PLAIN, 16)))));
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
    }

    class IconImage extends BufferedImage{
        public IconImage(String text, Font font){
            super(..., ..., BufferedImage.TYPE_INT_ARGB);//*****Unknown dimensions*****

            Graphics2D g2d = (Graphics2D) this.getGraphics();
            g2d.setFont(font);
            g2d.setColor(Color.BLACK);

            int stringHeight = (int) g2d.getFontMetrics().getStringBounds(text, g2d).getHeight();  
            g2d.drawString(text, 0 , stringHeight);
            g2d.dispose();
        }
    }

    public static void main(String[] args){
        new Test(); 
    }
}

有什么建议吗?感谢。

2 个答案:

答案 0 :(得分:2)

两种可能的解决方案:

  1. 创建一个小的BufferedImage(1x1)只是为了获取Graphics对象并进行计算。然后创建真实的图像
  2. 创建任意尺寸的BufferedImage,并将文本缩放到BufferedImage的大小。有关缩放的示例,请参阅StandardPrint.preview

答案 1 :(得分:2)

我只发现了相对环节的代码。 需要FontMetrics,它取决于granphics设备(屏幕/打印机)。

因此我制作了一个与屏幕兼容的超大图像。

static BufferedImage textToImage(Font font, String text) {
    BufferedImage testImg = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getDefaultScreenDevice()
            .getDefaultConfiguration()
            .createCompatibleImage(1000, 100);
    FontMetrics fm;

    Graphics2D g = testImg.createGraphics();
    g.setFont(font);
    fm = g.getFontMetrics(font);
    Rectangle2D bounds = fm.getStringBounds(text, g);
    System.out.println("Bounds: " + bounds);
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, testImg.getWidth(), testImg.getHeight());
    g.setColor(Color.MAGENTA.darker());
    g.drawString(text, 0, fm.getHeight() - fm.getDescent());
    g.dispose();

    Rectangle viewR = new Rectangle(0, 0, 1000, 100);
    Rectangle iconR = new Rectangle();
    Rectangle textR = new Rectangle();
    String displayedText = SwingUtilities.layoutCompoundLabel(fm, text, null,
                     SwingConstants.TOP, SwingConstants.LEFT, 0, 0,
                     viewR, iconR, textR, 0);

    System.out.println("textR: " + textR);
    BufferedImage img = testImg.getSubimage(0, 0, textR.width, textR.height);
    return img;
}

字符串边界是浮点矩形。通过比较使用SwingUtilities.layoutComponentLabel,可以看到边界向上舍入了一个半像素:字体可能会移动像素部分以获得锐边。