web-dev-qa-db-ja.com

Graphicsオブジェクトを使用せずに文字列を測定しますか?

フォントの単位としてピクセルを使用しています。 1つの場所で、ヒットテストを実行して、ユーザーが画面上のテキストの境界の四角形内をクリックしたかどうかを確認しています。これにはMeasureStringのようなものを使用する必要があります。残念ながら、ヒットテストを実行するコードは、GraphicsオブジェクトまたはControlにさえアクセスできないライブラリの深いところにあります。

Graphicsクラスを使用せずに、フォントを指定して文字列のバウンディングボックスを取得するにはどうすればよいですか?フォントがピクセルの場合、Graphicsオブジェクトが必要なのはなぜですか?

41
Agnel Kurian

System.Windows.Formsへの参照がある場合は、TextRendererクラスを使用してみてください。文字列とフォントを受け取り、サイズを返す静的メソッド(MeasureText)があります。 MSDNリンク

47
Jarrod

計測にレンダリングするために使用しているグラフィックスオブジェクトを使用する必要はありません。静的ユーティリティクラスを作成できます。

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var image = new Bitmap(1, 1))
        {
            using (var g = Graphics.FromImage(image))
            {
                result = g.MeasureString(s, font);
            }
        }

        return result;
    }
}

状況に応じて、ビットマップのdpiを設定することもできます。

23
NerdFury

@NerdFury回答のMeasureStringメソッドは、予想よりも文字列の幅が広くなります。追加情報 ここ を見つけることができます。物理的な長さのみを測定する場合は、次の2行を追加してください。

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = 
  g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);
11
Anton Putov

この例は、FormattedTextの使用法を説明するのに優れています。 FormattedTextは、Windows Presentation Foundation(WPF)アプリケーションでテキストを描画するための低レベルのコントロールを提供します。これを使用して、グラフィックスオブジェクトを使用せずに、特定のフォントの文字列の幅を測定できます。

public static float Measure(string text, string fontFamily, float emSize)
{
    FormattedText formatted = new FormattedText(
        item, 
        CultureInfo.CurrentCulture, 
        System.Windows.FlowDirection.LeftToRight, 
        new Typeface(fontFamily), 
        emSize, 
        Brushes.Black);

    return formatted.Width;
}

WindowsBaseおよびPresentationCoreライブラリを含めます。

1
Jacob Raines

これは他の人の繰り返しではないかもしれませんが、私の問題は不要なGraphicsオブジェクトでもありました。上記の不満を聞いた後、私は単に試しました:

Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);

(ここで、「コンテンツ」は測定する文字列であり、フォントはカードフォントです)

...そして運が良かった。結果を使用して、VSTOで列の幅を設定できます。

0
Peter Høgstedt