Как получить длину и высоту слов при рисовании изображений на холсте в GDI+

Я рисую строку на холсте, используя GDI+ в C++. Есть ли API для получения слоя (ширина, высота) строки определенным шрифтом? Спасибо большое! Большое спасибо решению программиста Windows. Я написал следующий код.

    Bitmap bitmap(1000,1000);
    Graphics graphics(&bitmap);
    RectF rec;
    RectF useless;
    graphics.MeasureString(m_sWords, -1, m_pFont.get(), useless, &rec);
    int WordWidth = rec.Width + 1;
    int WordHeight Height = rec.Height + 1;

Нужно ли использовать реальную графику для вызова MeasureString? Есть ли способ получить ширину слова,wordheight, без создания большого графического экземпляра? Я обнаружил, что это ресурс.

3 ответа

Graphics::MeasureString вычисляет приближение.

Чтобы сделать изображение завершенным: это можно просто сделать с помощью GraphicsPath, что лучше, так как не требует DeviceContext:

Dim p As New GraphicsPath

Using stringFormat As New StringFormat()
    stringFormat.Trimming = StringTrimming.EllipsisCharacter
    stringFormat.LineAlignment = StringAlignment.Center
    stringFormat.Alignment = StringAlignment.Near

    p.AddString(text, font.FontFamily, font.Style, font.SizeInPoints, Point.Empty, stringFormat)
End Using

Return p.GetBounds.Size

Где текст - заданная строка, а шрифт - заданный шрифт. Возвращает SizeF-структуру. Я обнаружил, что результаты были намного более точными, чем Graphics.MeasureString или GdipMeasureString-API.

К сожалению, вам нужно использовать Graphics объект, чтобы сделать это.

Код C#, который я использую (который возвращает RectangleF потому что я хочу знать ширину и высоту) выглядит следующим образом:

/// <summary> The text bounding box. </summary>
private static readonly RectangleF __boundingBox = new RectangleF(29, 25, 90, 40);

/// <summary>
///    Gets the width of a given string, in the given font, with the given
///    <see cref="StringFormat"/> options.
/// </summary>
/// <param name="text">The string to measure.</param>
/// <param name="font">The <see cref="Font"/> to use.</param>
/// <param name="fmt">The <see cref="StringFormat"/> to use.</param>
/// <returns> The floating-point width, in pixels. </returns>
private static RectangleF GetStringBounds(string text, Font font,
   StringFormat fmt)
{
   CharacterRange[] range = { new CharacterRange(0, text.Length) };
   StringFormat myFormat = fmt.Clone() as StringFormat;
   myFormat.SetMeasurableCharacterRanges(range);

   using (Graphics g = Graphics.FromImage(
       new Bitmap((int) __boundingBox.Width, (int) __boundingBox.Height)))
   {
      Region[] regions = g.MeasureCharacterRanges(text, font,
         __boundingBox, myFormat);
      return regions[0].GetBounds(g);
   }
}

Это вернет RectangleF размера всей текстовой строки, завернутый в слова по мере необходимости, в соответствии с ограничивающей рамкой, указанной как __boundingBox, С другой стороны, Graphics объект уничтожается, как только using заявление завершено...

Кроме того, GDI+ кажется довольно ненадежным в этом; Я обнаружил, что он довольно глючный (например, см. Мой вопрос "Graphics.MeasureCharacterRanges, который дает неверные вычисления размера в C#.Net?"). Если вы можете использовать TextRenderer.DrawText от System.Windows.Forms, тогда делай.

Другие вопросы по тегам