java - 无法获得正确的字体字符宽度

标签 java fonts java-2d

这是一个将 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(粗体、斜体)。

这就是字体的渲染方式 enter image description here

编辑:

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

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

最佳答案

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

Javadoc对于 FontMetrics.charWidth(char ch):

The advance is the distance from the leftmost point to the rightmost point on the character's baseline

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

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

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

关于java - 无法获得正确的字体字符宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15816376/

相关文章:

java - 无法为程序创建启动画面,还有颜色问题?

javascript - 如何通过引用 .js 文件来呈现这些字体?

java - JPanel 和 BufferedImage

java - Autowiring 到不同的bean

java - 更新了 util.scanner 重复方法

css - 更改WordPress主题的字体 "Zerif Lite"

java - 使用像素在 Canvas 上绘制 PNG;公式?

Java2D的drawString很慢?

java - 如何在java中使用正则表达式从单词末尾删除ing

java - 更改 Hadoop 上随机数据生成的大小