我需要打印文字,例如标签的“产品名称”,由来自JAVA的300 dpi标签打印机打印。 字体是Arial。 FontSize 6。 如何计算文本的宽度(以mm为单位)?
String fontName = "Arial";
int fontSize = 6;
String string = "Product name";
Font font = new Font(fontName, Font.PLAIN, fontSize);
Canvas c = new Canvas();
FontMetrics fm = c.getFontMetrics(font);
int i = fm.stringWidth(string);
在上面的代码中,i = 36。但“36”是什么意思?当使用300DPI打印机打印在标签上时,如何获得以毫米为单位的宽度?
答案 0 :(得分:1)
您想要的课程是FontMetrics
,您可以从Graphics2D
对象获取该课程。
获得FontMetrics对象后,您可以使用charsWidth
,getHeight
和getAscent
等方法来确定字符串的适当宽度和高度(取决于您的身份)表示'高度',请参阅第73页上的说明here以了解有关字体大小的一些基本知识(以像素为单位)。
如你所知,像素与纸上英寸不同 - 但如果你知道打印机的DPI,你应该能够通过除法确定以英寸为单位的大小:像素/ DPI =英寸。
答案 1 :(得分:1)
您问题中的代码是调用new Canvas()
,它将假设您的屏幕是预期的输出设备,从而为不同系统上的不同行为创造潜力。
This doc明确表示Java 2D中的用户空间应为每英寸72个单位。 FontMetrics的Javadoc并没有明确它返回的单位,但它是用户空间坐标是有意义的。这意味着你看到的36是36/72英寸,这是12.7毫米。
更新2:
您的问题没有说明如何将渲染文本提供给打印机,因此您可能已经有一个Graphics或Graphics2D对象,可以从中获取实际输出设备上下文中的字体指标。如果不这样做,以下代码应创建独立于屏幕的图形上下文:
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
FontMetrics fm = g.getFontMetrics(new Font("Arial", Font.PLAIN, 6));
int width = fm.stringWidth("Product name");
结果仍为36,单位为1/72英寸。
更新3:
在下图中,字符串“NCW”显示在Arial中,由Java呈现。矩形的底部是基线,矩形的左下角是我告诉Java绘制字符串的点。如上所述,矩形的宽度输出fm.stringWidth()
。 (矩形的顶部是任意的。)您可以看到字符串宽度不是文本接触基线的点,但也不是从最左边到最右边填充像素的距离。相反,它是沿着基线向右前进,从这个字符串被绘制到通常绘制下一个字符串的位置。
C和W之间的间距是字距调整的一个很好的例子。字体设计者还选择使C的底边稍微延伸到基线以下,因为除非您作弊,否则圆形形状看起来不会与直线形状对齐。请注意N的左边是否有一些空间,而W的右边空间要小得多。这也是因为C和W之间的空间较小:使它看起来正确。如果字体设计师想要的话,他可以将W扩展到框外,就像C在它下面延伸一样。
最终结果是字母形式的视觉权重应该均匀分布,因此该框的中心应该是文本的视觉中心。所以你应该能够忽略我刚刚说过的所有内容,将一半的字符串宽度添加到起点,称之为中心,并且开心。
如果结果看起来不是您的中心,那么您的数学错误,或者您的打印代码中的某些内容没有按照您的想法进行,或者字体设计师根本没有平衡视觉重量按照你的喜好。如果是后者,请随意申请一些艺术许可,并将其捏造到您喜欢的地方。