13

我正在使用 GDI+ 在 Graphics 对象上绘制一个字符串。

我希望字符串适合预定义的矩形(不破坏任何线条)

除了在循环中使用 TextRenderer.MeasureString() 直到返回所需的大小之外,还有其他方法吗?

就像是:

DrawScaledString(Graphics g, string myString, Rectangle rect)
4

2 回答 2

8

您可以使用 ScaleTransform

string testString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse et nisl adipiscing nisl adipiscing ultricies in ac lacus.
Vivamus malesuada eros at est egestas varius tincidunt libero porttitor.
Pellentesque sollicitudin egestas augue, ac commodo felis ultricies sit amet.";

Bitmap bmp = new Bitmap(300, 300);
using (var graphics = Graphics.FromImage(bmp))
{
    graphics.FillRectangle(Brushes.White, graphics.ClipBounds);
    var stringSize = graphics.MeasureString(testString, this.Font);
    var scale = bmp.Width / stringSize.Width;
    if (scale < 1)
    {
        graphics.ScaleTransform(scale, scale);
    }
    graphics.DrawString(testString, this.Font, Brushes.Black, new PointF());
}
bmp.Save("lorem.png", System.Drawing.Imaging.ImageFormat.Png);

但是你可能会得到一些别名效果。

替代文字

编辑:

但是,如果您想更改字体大小,我想您可以scale在上面的代码中更改字体大小,而不是使用缩放变换。尝试两者并比较结果的质量。

于 2010-11-11T09:45:14.040 回答
5

这是该问题的另一种解决方案,它有点密集,因为它需要相当多的字体创建和销毁,但可能会更好,具体取决于您的情况和需要:

public class RenderInBox
{
    Rectangle box; 
    Form root;
    Font font;
    string text;

    StringFormat format;

    public RenderInBox(Rectangle box, Form root, string text, string fontFamily, int startFontSize = 150)
    {
        this.root = root;
        this.box = box;
        this.text = text;

        Graphics graphics = root.CreateGraphics();

        bool fits = false;
        int size = startFontSize;
        do
        {
            if (font != null)
                font.Dispose();

            font = new Font(fontFamily, size, FontStyle.Regular, GraphicsUnit.Pixel);

            SizeF stringSize = graphics.MeasureString(text, font, box.Width, format);

            fits = (stringSize.Height < box.Height);
            size -= 2;
        } while (!fits);

        graphics.Dispose();

        format = new StringFormat()
        {
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center
        };

    }

    public void Render(Graphics graphics, Brush brush)
    {
        graphics.DrawString(text, font, brush, box, format);
    }
}

要使用它,只需创建一个新类并调用 Render()。请注意,这是专门为呈现到表单而编写的。

var titleBox = new RenderInBox(new Rectangle(10, 10, 400, 100), thisForm, "This is my text it may be quite long", "Tahoma", 200);
titleBox.Render(myGraphics, Brushes.White);

您应该预先创建 RenderInBox 对象,因为它具有密集的创建性质。因此,它并不适合所有需要。

于 2012-02-23T08:11:23.203 回答