2010-11-11 107 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