2013-10-23 54 views
2

我需要打印文本,例如「產品名稱」由標籤打印機打印出來,由JAVA打印。 字體是Arial。 FontSize 6. 如何計算文本的寬度(單位:毫米)?如何獲得在300 dpi標籤打印機上打印的文本的高度和寬度?

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

你試過的代碼在哪裏? – Engineer

+0

我試過這個,但與graphics2D混淆:String str =「Hello World」; Font font = new Font(「Arial」,0,6); Graphics2D ig2; BufferedImage bi = new BufferedImage(150,100,BufferedImage.TYPE_INT_ARGB); ig2 = bi.createGraphics(); Rectangle2D r2D = font.getStringBounds(str,ig2.getFontRenderContext()); –

+0

請[編輯]您的問題以包含代碼。 – Uooo

回答

1

您問題中的代碼正在調用new Canvas(),它將假定您的屏幕是預期的輸出設備,從而爲不同系統上的不同行爲創建潛力。

This doc明確表示,Java 2D中的用戶空間旨在爲每英寸72個單位。 FontMetrics的Javadoc並不清楚它返回的單元,但它是用戶空間座標是有意義的。這意味着你看到的36是36/72英寸,這是12.7毫米。

更新2:

你的問題沒有說你是如何得到呈現的文本到打印機,所以你可能已經有了一個圖形或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()的輸出。 (矩形的頂部是任意的。)您可以看到,字符串寬度不是關於文本接觸到基線的點,但它也不是從最左側到最右側填充像素的距離。相反,從繪製字符串的位置到通常繪製下一個字符串的位置的基線向右前進。

Image produced by short Java program to demonstrate stringWidth

的C和W之間的間距是字距調整的一個很好的例子。字體設計者也選擇使C的底邊稍微低於基線,因爲除非你作弊,否則圓形看起來並不直接與直線形狀對齊。注意N的左邊有一些空間,W右邊的空間少得多。這也是出於同樣的原因,C和W之間的空間更小:使它看起來正確。如果字體設計師想要的話,他可以讓W延伸到盒子外面,就像C延伸到盒子下面一樣。

最終的結果是,信件形式的視覺重量應當均勻分佈,因此該盒子的中心應該是文本的視覺中心。所以你應該能夠忽略我剛剛說的所有事情,將字符串寬度的一半添加到起始點,稱之爲中心,然後開心。

如果結果不是以你爲中心的,那麼要麼你的數學錯誤,要麼是你的打印代碼中的某些東西沒有做你認爲正在做的事情,或者字體設計者根本沒有平衡視覺重量符合你的喜好。如果是後者,隨時可以申請一些藝術品許可證並將其粘貼到你喜歡的地方。

+0

感謝您的發佈。有沒有什麼辦法,我可以確保獲得文本的正確寬度,然後呢? –

+0

@JakobMathiasen使用我將用來獲取字符串寬度的代碼更新答案。 – gatkin

+0

感謝您的回答。我可以使用這個..一個小問題是,stringWidth(「xxx」)方法給出從基線起點到基線終點的長度,而不是從整體起點到終點。在所有這方面的文檔中,他們都說我不能依靠每個字符的寬度來獲得結果,並將它們加在一起。 –

1

您想要的課程是FontMetrics,您可以從您的Graphics2D對象中獲得該課程。

一旦你得到了FontMetrics對象,你可以像使用charsWidthgetHeightgetAscent方法來確定您的字符串的適當的寬度和高度(取決於你所說的什麼「高度」,看到頁面上的說明以瞭解字體大小的一些基本知識)(以像素爲單位)。如您所知,像素與紙上英寸不一樣 - 但如果您知道打印機的DPI,則應該能夠通過除法確定以英寸爲單位的尺寸:像素/ DPI =英寸。

+0

有沒有辦法避免Graphics2D,當我想計算字符串的寬度? –

+0

我想你問的問題沿着這個問題的線:http://stackoverflow.com/questions/10677876/java-graphics-constructing-fontmetrics-from-font-without-a-graphics2d – arthegall

+0

感謝您的鏈接。當我實現這個時,我得到(example)stringWidth(「product name」)= 37。但是在這種情況下,「37」是什麼意思? 37像素? 37/300 = 0.1233英寸= 3.1毫米。但是標籤上的字符串實際上是12毫米。 –

相關問題