我正在使用GDI +在Graphics对象上绘制字符串。
我希望字符串适合预定义的矩形(不破坏任何行)
除了在循环中使用TextRenderer.MeasureString()之外,是否还有这样做,直到返回所需的大小?
类似的东西:
DrawScaledString(Graphics g, string myString, Rectangle rect)
答案 0 :(得分: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
更改字体大小,而不是使用缩放变换。尝试两者并比较结果的质量。
答案 1 :(得分: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对象,因为它具有密集的创建特性。因此,它并不适合所有需要。