2010-11-11 104 views
12

我正在使用GDI +在Graphics对象上绘制字符串。在矩形内填充文本

我想字符串以满足预先定义的矩形内(不违反任何行)

是否有反正在循环中使用TextRenderer.MeasureString(),直到返回所需尺寸这样除了吗?

类似:

DrawScaledString(Graphics g, string myString, Rectangle rect) 
+0

你可以应用一个矩阵变换,但是自从我上次触及它以来已经有很多年了。 – leppie 2010-11-11 09:28:56

+0

这不是一点开销吗? – Nissim 2010-11-11 09:31:39

回答

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); 

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

alt text

编辑:

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

+0

谢谢你......我根据比例改变了字体大小,做了小小的调整,效果很好...... – Nissim 2010-11-11 10:58:08

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对象,因为它的密集创建特性。因此它不适合每个需要。

+0

非常好,正是我需要的! – Gromer 2012-07-26 19:53:15