这是一个将 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);
最佳答案
我认为这是因为提前或 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/