2012-07-29 10 views
5

En primer lugar, la pregunta How to measure width of character precisely? que se responde, realmente no ayuda para este caso, por lo que este no es un duplicado de ese.cómo medir el ancho de una cuerda con precisión?

Tengo una cadena. Dibujo usando graphics.DrawString, sin embargo, cuando necesito poner otro después, necesito saber el ancho exacto de la cadena anterior.

Para ello utilizo graphics.MeasureString con:

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

He intentado muchas otras funciones, tal como TextRendered.MeasureText sin embargo todas ellas fallar, con todas las posibles combinaciones de parámetros.

la combinación mencionada de MeasureString está más cerca de lo que necesito (funciona en la mayoría de los casos, excepto en el caso de caracteres especiales), sin embargo, usa caracteres como # break it. El ancho es más corto o más largo.

¿Hay alguna manera de obtener un tamaño preciso de texto producido por la función DrawString? ¿Cómo calcula DrawString el tamaño del área de dibujo? Debe ser claramente alguna otra función porque el tamaño siempre difiere.

El código fuente de la aplicación entera está aquí https://gitorious.org/pidgeon/pidgeon-main/ (Archivo donde trabajo con esto, es https://gitorious.org/pidgeon/pidgeon-main/blobs/master/scrollback/SBABox.cs)

+0

posible duplicado de ([Cómo medir el ancho de píxel de la cadena dibujada sobre Drawing.Bitmap en .NET?] http://stackoverflow.com/questions/2555739/how-to-measure-the-pixel-width-of-the-string-drawed-over-drawing-bitmap-in-net) –

+0

si la pregunta claramente no dice MeasureString no funciona, sería un duplicado – Petr

+0

Sin una mejor descripción de cómo y cuándo "no funciona", y un código que incluye MeasureString y DrawString juntos, esto simplemente no es una pregunta real. Vamos con una pequeña caja de prueba. –

Respuesta

7

Sólo tiene que eliminar la anchura adicional. Usted puede hacer esto mediante el uso de string format:

GdipStringFormatGetGenericTypographic() 

También es posible usar:

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

Esto le permitirá trabajar con otros idiomas como el japonés.

On codeproject, la solución de Pierre Anaud era utilizar MeasureCharacterRanges, que devuelve una región coincide exactamente con el cuadro delimitador de la cadena especificada:

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

parecía funcionar hasta que encontré algunos problemas con el formato, cuando lo arreglé, toda la función acaba de comenzar a devolver el mismo valor incorrecto que MeasureString ... – Petr

+1

funciona bien ... solo soluciona esa línea: ** formato. SetMeasurableCharacterRanges (new CharacterRange [] {ranges}); ** – ymz

1

intenta utilizar estos métodos:

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

También puede ayudarlo:

escribir un método de medida personalizada:

  • cadena de entrada Dividir en caracteres especiales
  • uso por encima de los métodos .net
  • Calcular anchura de los caracteres especiales y suma ...

Read Ian Boyd answer

2

Llego un poco tarde a la fiesta aquí, pero estaba tratando de hacer algo similar y tropecé con esta pregunta.Probablemente ya has visto la siguiente observación de the documentation for the Graphics.MeasureString method on MSDN:

El método MeasureString está diseñado para su uso con cuerdas individuales e incluye una pequeña cantidad de espacio adicional antes y después de la cadena para permitir que sobresale por glifos. Además, el método DrawString ajusta los puntos de glifo para optimizar la calidad de visualización y puede mostrar una cadena más estrecha que la informada por MeasureString. Para obtener métricas adecuadas para cadenas adyacentes en el diseño (por ejemplo, al implementar texto formateado), use el método MeasureCharacterRanges o uno de los métodos MeasureString que tome StringFormat y pase GenericTypographic. Además, asegúrese de que TextRenderingHint para Graphics es AntiAlias.

Parece que estuviera tratando de seguir este consejo porque usted está utilizando StringFormat.GenericTypographic como punto de partida para el objeto personalizado StringFormat. Sin embargo, la línea

format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; 

niega efectivamente el hecho de que usted comenzó con StringFormat.GenericTypographic ya que borra cualquier indicadores establecidos previamente. Lo que probablemente significaba que hacer es establecer el indicador StringFormatFlags.MeasureTrailingSpaces preservando al mismo tiempo las otras banderas, así:

format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; 
Cuestiones relacionadas