1

这是一种将 awt 字体字符作为缓冲图像返回的方法:

private BufferedImage getCharImage(char ch) {
    BufferedImage sizeImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
    Graphics2D sizeGraphics = (Graphics2D) sizeImage.getGraphics();
    if (antiAlias) {
        sizeGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }

    FontMetrics fontMetrics = sizeGraphics.getFontMetrics(font);
    int charwidth = fontMetrics.charWidth(ch);
    if (charwidth <= 0) {
        charwidth = 1;
    }

    int charheight = fontMetrics.getHeight();
    if (charheight <= 0) {
        charheight = fontSize;
    }

    BufferedImage charImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB);
    Graphics2D charGraphics = (Graphics2D) charImage.getGraphics();

    if (antiAlias) {
        charGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }

    charGraphics.setFont(font);
    charGraphics.setColor(Color.WHITE);
    charGraphics.drawString(String.valueOf(ch), 0, fontMetrics.getAscent());

    return charImage;
}

问题是我得到不正确的宽度,并且字符不适合装箱缓冲图像。如果我像这样创建缓冲图像,new BufferedImage(charwidth + 10, charheight, BufferedImage.TYPE_INT_ARGB);则字符将适合图像(这意味着我得到错误的字体宽度)。为什么我面临这个问题,我该如何解决?我正在使用 arialbi.ttf(粗体,斜体)。

这就是字体呈现的方式 在此处输入图像描述

编辑:

这就是我定义字体变量的方式:

    font = Font.createFont(Font.TRUETYPE_FONT, inputStream);
    font = font.deriveFont(fontSize);
4

2 回答 2

2

我认为这是因为提前,或者charWidth()与字体定义的字符的实际宽度没有太大关系。

Javadoc用于FontMetrics.charWidth(char ch)

前进是从角色基线上最左边的点到最右边的点的距离

像 Chancery Italic 中的“g”这样的字符,位于基线下方,延伸到最小值 x 的左侧。或相同字体的“s”在最大 x 的右侧延伸到基线上方。在更直的字体中,如 Arial Regular,前进(基线宽度)恰好非常接近字符的实际宽度。

除了添加任意填充之外,我不确定一个好的解决方案。

另请参阅:http ://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html

于 2013-04-26T17:11:00.060 回答
1

我相信这是获得字符串的确切宽度所需要的:

FontMetrics fontMetricesForLabel = graphics.getFontMetrics();
double width = fontMetricesForLabel.getStringBounds(label, graphics).getWidth();
于 2019-06-10T11:21:28.837 回答