2012-07-29 79 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的提到的組合最接近我需要的東西(它在大多數情況下工作,除了特殊字符),但是使用像#這樣的字符打斷它。寬度可以更短或更長。

有沒有辦法讓DrawString函數產生精確的文本大小? DrawString如何計算繪圖區域的大小?它必須清楚地表明其他功能,因爲尺寸總是不同的。

整個應用程序的源代碼是在這裏https://gitorious.org/pidgeon/pidgeon-main/(文件,我這個工作,是https://gitorious.org/pidgeon/pidgeon-main/blobs/master/scrollback/SBABox.cs

+0

可能重複([如何衡量字符串的像素寬度在.NET drawed超過Drawing.Bitmap?] http://stackoverflow.com/questions/2555739/how-to-measure-the-pixel-width-of-the-string-drawed-over-drawing-bitmap-in-net) – 2012-07-29 11:36:23

+0

如果問題沒說清楚MeasureString不工作,這將是重複的 – Petr 2012-07-29 14:49:57

+0

沒有怎樣及何時「它不工作」更好的說明和代碼,包括MeasureString和束帶在一起,這恰恰是不是一個真正的問題。拿出一個小小的測試用具。 – 2012-07-29 16:12:00

回答

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 2012-07-29 14:44:59

+1

工作得很好......唯一的解決方法就是行:**格式。 SetMeasrableCharacterRanges(new CharacterRange [] {ranges}); ** – ymz 2016-01-21 11:51:18

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方法,需要一個一個StringFormat,並通過GenericTypographic。同時,確保TextRenderingHintGraphicsAntiAlias

您似乎在嘗試遵循此建議,因爲您使用的是StringFormat.GenericTypographic作爲自定義StringFormat對象的起點。然而,該行

format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

有效地否定了,你開始StringFormat.GenericTypographic,因爲它會清除所有以前設置的標誌的事實。你大概意思做的是設置StringFormatFlags.MeasureTrailingSpaces標誌,同時保留其他標誌,就像這樣:

format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;