2012-07-29 67 views
5

まず、質問How to measure width of character precisely?は、は本当にこの場合は役に立たないので、これはの複製ではありません。文字列の幅を正確に測定する方法は?

私は文字列を持っています。 graphics.DrawStringを使用して描画しますが、後に別の文字を配置する必要がある場合は、前の文字列の正確な幅を知る必要があります。私はgraphics.MeasureStringを使用し、このために

StringFormat format = new StringFormat(StringFormat.GenericTypographic); 
format.Alignment = StringAlignment.Center; 
format.Trimming = StringTrimming.None; 
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

しかし私はそれらのすべては、パラメータのすべての可能な組み合わせで、失敗ばかりTextRendered.MeasureTextとして、他の多くの機能を試してみました。

上記のMeasureStringの組み合わせは、私が必要とするものに最も近いです(ほとんどの場合、特殊文字を除いて動作します)。ただし、#breakなどの文字を使用します。幅は短くても長くてもよい。

DrawString関数によって生成されるテキストの正確なサイズを取得する方法はありますか? DrawStringは描画領域のサイズをどのように計算しますか?それはサイズが常に異なるので、明らかに他の機能でなければなりません。

アプリケーション全体のソースコードはここにhttps://gitorious.org/pidgeon/pidgeon-main/です(私はこれで動作するファイルは、https://gitorious.org/pidgeon/pidgeon-main/blobs/master/scrollback/SBABox.csある)

+0

可能複製([文字列のピクセル幅を測定するために、どのように.NETでDrawing.Bitmap上drawed?] http://stackoverflow.com/questions/2555739/how-to-measure-the-pixel-width-of-the-string-drawed-over-drawing-bitmap-in-net) –

+0

質問が明らかにしなかった場合MeasureStringは機能しません。重複しています – Petr

+0

「動作しません」とMeasureStringとDrawStringが一緒に含まれているコードについては、実際の質問ではありません。小さなテストケースを用意しましょう。 –

答えて

7

あなただけの余分な幅を排除する必要があります。あなたはstring formatを使用してこれを行うことができます。

GdipStringFormatGetGenericTypographic() 

はまた、使用することができます

float doubleWidth = g.MeasureString(text+text,...).Width; 
float singleWidth = g.MeasureString(text).Width; 
float textWidth = doubleWidth-singleWidth; 

これは、このような日本のなどの他の言語で動作するようになります。

On codeproject、ピエールAnaudのソリューションは、指定された文字列の正確バウンディングボックスに一致する地域を返す、MeasureCharacterRangesを使用していた:

static public int MeasureDisplayStringWidth(Graphics graphics, string text, Font font) 
{ 
    System.Drawing.StringFormat format = new System.Drawing.StringFormat(); 
    System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000); 
    var ranges = new System.Drawing.CharacterRange(0, text.Length); 
    System.Drawing.Region[] regions = new System.Drawing.Region[1]; 

    format.SetMeasurableCharacterRanges (ranges); 

    regions = graphics.MeasureCharacterRanges (text, font, rect, format); 
    rect = regions[0].GetBounds (graphics); 

    return (int)(rect.Right + 1.0f); 
} 
+0

フォーマットでいくつかの問題が見つかるまで動作するように見えましたが、私はそれを修正して、関数全体がMeasureStringと同じ誤った値を返すようになったばかりです... – Petr

+1

はうまくいきます。 SetMeasurableCharacterRanges(新しいCharacterRange [] {ranges}); ** – ymz

1

は、このメソッドを使用してみてください:

GDI+ (graphics.MeasureString and graphics.DrawString) >> System.Drawing.Graphics 
GDI (TextRenderer.MeasureText and TextRenderer.DrawText) 

また、あなたに役立つかもしれません:

は、カスタム測定方法書く:特殊文字の

  • スプリットエントリ文字列を.NET方法上記
  • 使用
  • 特殊文字と和の
  • 計算幅...

Read Ian Boyd answer

2

私はここでパーティーに少し遅れましたが、私は同様のことをやろうとしていて、この質問に遭遇しました。あなたはおそらくすでにthe documentation for the Graphics.MeasureString method on MSDNから次の発言を見てきました:

MeasureString方法は、個々の文字列で使用するために設計されており、オーバーハングのグリフを可能にするために、文字列の前後に余分なスペースを少量含まれています。また、DrawStringメソッドは、グリフポイントを調整して表示品質を最適化し、MeasureStringよりも狭い文字列を表示することがあります。レイアウト内の隣接する文字列に適したメトリックを取得するには、MeasureCharacterRangesメソッドまたはMeasureStringメソッドのうちの1つをStringFormatとし、GenericTypographicを渡します。また、GraphicsTextRenderingHintAntiAliasであることを確認してください。

あなたがあなたのカスタムStringFormatオブジェクトのための出発点としてStringFormat.GenericTypographicを使用しているので、このアドバイスに従うことをしようとしていたようです。しかし、ライン

format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

が効果的に、それは以前に設定されたフラグをクリアしますので、あなたがStringFormat.GenericTypographicを始めているという事実を否定します。あなたはおそらく、他のフラグを維持しながら、そのように、StringFormatFlags.MeasureTrailingSpacesフラグを設定されてやって何を意味するのか:

format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; 
関連する問題