4

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 プリンターでラベルに印刷した場合、幅をミリ単位で取得するにはどうすればよいですか?

4

2 に答える 2

2

あなたの質問のコードは、new Canvas()あなたの画面が意図された出力デバイスであると仮定しようとしている呼び出しであり、異なるシステムで異なる動作の可能性を生み出します.

このドキュメントでは、Java 2D のユーザー空間は 1 インチあたり 72 ユニットを意図していると明示的に述べています。FontMetrics の Javadoc は、返される単位について明示的ではありませんが、ユーザー空間座標であることは理にかなっています。つまり、表示されている 36 は 36/72 インチ、つまり 12.7 mm です。

更新 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");

結果は 1/72 インチ単位で 36 のままです。

更新 3:

下の画像では、文字列「NCW」が、Java によってレンダリングされた Arial で示されています。長方形の下部がベースラインで、長方形の左下隅が Java に文字列を描画するように指示したポイントです。長方形の幅はfm.stringWidth()上記のように出力されます。(四角形の上部は任意です。) 文字列の幅は、テキストがベースラインに接する点に関するものではありませんが、左端から右端の塗りつぶされたピクセルまでの距離でもないことがわかります。むしろ、この文字列が描かれた場所から次の文字列が通常描かれる場所までのベースラインに沿った右方向の前進です。

stringWidth を示すために短い Java プログラムによって生成された画像

C と W の間の間隔は、カーニングの良い例です。フォント デザイナーは、C の下端をベースラインよりわずかに下に延長することも選択します。N の左側にスペースがあり、W の右側にスペースが少ないことに注意してください。これは、C と W の間のスペースが少ないのと同じ理由で、正しく見えるようにするためです。フォント デザイナーが望むのであれば、C がボックスの下に伸びるように、W をボックスの外に拡張することもできたはずです。

最終的な結果として、文字フォームの視覚的な重みが均等に分散されるため、そのボックスの中心がテキストの視覚的な中心になるはずです。ですから、今言ったことはすべて無視して、弦幅の半分を開始点に追加し、それを中心と呼んで満足できるはずです。

結果が中央に表示されない場合は、計算が間違っているか、印刷コードの何かが思ったとおりに動作していないか、フォント デザイナーが視覚的な重みを好みに合わせて調整していないだけです。 . 後者の場合は、芸術的なライセンスを自由に適用して、好きな場所に移動してください。

于 2013-10-23T19:35:07.663 に答える