我正在尝试编写一个需要将字符串绘制到图像的函数。图像具有1-5个文本框,每个文本框都有x,y,宽度和高度。这些细节在我正在解析的XML文件中定义,因此我可以访问每个框。
我的问题是我是否可以使用graphics.DrawString(或类似的)方法轻松完成此操作。下面的示例函数将创建一个具有指定的x,y,width,height的矩形,然后在其中绘制一个字符串。如果字符串不适合,则会截断。
public void DrawStringRectangleFormat(Graphics g)
{
// Create string to draw.
String drawString = "Sample Text is too long to fit into this tiny lil rectangle area right here";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create rectangle for drawing.
float x = 150.0F;
float y = 150.0F;
float width = 200.0F;
float height = 50.0F;
RectangleF drawRect = new RectangleF(x, y, width, height);
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawRect, drawFormat);
}
我想要的不是这个,而是截断,它将停在最后一个拟合词,然后转到下一个矩形(文本框)。这样我就可以使用所有可用的文本框。
有没有一种方法可以做到这一点?否则我将需要实现自己的drawString方法。
答案 0 :(得分:1)
好的,您需要做的是遍历字符串中的每个字符串,并连接到最终的字符串.. 所以基本上foreach(mysc中的char c)... 然后使用measuretring,检查字符串是否超过框长度,如果是,则从下一个矩形开始...
https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx
答案 1 :(得分:1)
此解决方案使用StringFormat
的设置来确保每次调用DrawString只绘制适合的单词。然后,Graphics.MeasureCharacterRanges
计算不适合矩形的单词,剩下的文本溢出到下一个布局矩形中。
您可能需要自定义输入字符串如何拆分为单词。现在我只是把它分开在空白边界。
using System.Text.RegularExpressions;
using System.Drawing;
/// <summary>
/// Draw a string using one or more layout rectangles. Words which don't fit will overflow into the next layout rectangle.
/// </summary>
private static void DrawOverflowString(Graphics graphics, string drawString, RectangleF[] layoutRectangles, StringAlignment alignment)
{
var drawFont = new Font("Arial", 16.0f);
var black = new SolidBrush(Color.Black);
var format = new StringFormat()
{
Alignment = alignment,
Trimming = StringTrimming.Word,
FormatFlags = StringFormatFlags.LineLimit
};
var wordRegex = new Regex("[^\\s]+");
string remainingText = drawString;
foreach (var layoutRect in layoutRectangles)
{
// Draw everything that will fit into this text box
graphics.DrawString(remainingText, drawFont, black, layoutRect, format);
// calculate which words did not fit
var wordMatches = wordRegex.Matches(remainingText);
var ranges = wordMatches.OfType<Match>().Select(x => new CharacterRange(x.Index, x.Length)).ToArray();
format.SetMeasurableCharacterRanges(ranges);
var wordRegions = graphics.MeasureCharacterRanges(remainingText, drawFont, layoutRect, format);
var allfit = true;
for (int i = 0; i < wordRegions.Length; i++)
{
if (wordRegions[i].GetBounds(graphics).Width == 0.0f)
{
allfit = false;
remainingText = remainingText.Substring(wordMatches[i].Index);
break;
}
}
if (allfit)
break;
}
drawFont.Dispose();
black.Dispose();
}
答案 2 :(得分:1)
protected override void OnPaint(PaintEventArgs e)
{
// Call the OnPaint method of the base class.
base.OnPaint(e);
List<Rectanglestring> testrecs = new List<Rectanglestring>();
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 12, 40, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring {targetrect= new Rectangle(0, 25, 35, 12),whattodraw="" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 35, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 45, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 65, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 85, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 95, 55, 12), whattodraw = "" });
string mystringtofit = "This is just an example";
foreach (Rectanglestring rect in testrecs)
{
for (int i = 0; i < mystringtofit.Length; i++)
{
if (mystringtofit[i] == ' ' && rect.whattodraw.Length > 0) break;
if (mystringtofit[i] == ' ') continue;
string teststring = rect.whattodraw + mystringtofit[i];
SizeF stringSize = stringSize = e.Graphics.MeasureString(teststring, new Font("Ariel", 12));
if (stringSize.Width >= rect.targetrect.Width) break;
rect.whattodraw += mystringtofit[i];
}
mystringtofit = mystringtofit.Substring(rect.whattodraw.Length);
if (mystringtofit.StartsWith(" "))
{
mystringtofit = mystringtofit.Substring(1);
}
e.Graphics.DrawString(rect.whattodraw, Font, new SolidBrush(ForeColor), rect.targetrect);
}
// Call methods of the System.Drawing.Graphics object.
}
public class Rectanglestring
{
public Rectangle targetrect = new Rectangle();
public string whattodraw = "";
}
答案 3 :(得分:0)
这就是我所拥有的。它做我所描述的。谢谢你的回答。
public void DrawStringInTextboxes(string text, Graphics g)
{
String drawString = text;
PrivateFontCollection fontCollection = new PrivateFontCollection();
fontCollection.AddFontFile(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Fonts/Squidgingtons.ttf"));
var squidingtonsFontFamily = fontCollection.Families[0];
Font squidingtons = new Font(squidingtonsFontFamily, textParameters[0].MaxFontSize);
Font drawFont = new Font("Arial", 60);
SolidBrush drawBrush = new SolidBrush(Color.Black);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
char[] delimiterChars = { ' ' };
string[] words = drawString.Split(delimiterChars);
string finalString = "";
int textBoxIndex = 0;
foreach (string word in words)
{
//set the dimensions for the first textbox and create a rectangle with those specifications.
float x = textParameters[textBoxIndex].Left;
float y = textParameters[textBoxIndex].Top;
float width = textParameters[textBoxIndex].Width;
float height = textParameters[textBoxIndex].Height;
RectangleF Rect = new RectangleF(x, y, width, height);
//if the current finalString + the next word fits in the current box, add the word to finalString.
if (g.MeasureString(finalString + word + " ", squidingtons).Width < textParameters[textBoxIndex].Width)
{
finalString = finalString + " " + word;
//if this is the last word, print the finalString and we are done.
if (word == words[words.Length - 1])
{
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
break;
}
}
//the current finalString + next word did not fit in the box. Draw what we have to the first box.
else {
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
//Hold onto the word that didnt fit. It will be the first word of the next box.
finalString = word;
if (textBoxIndex +1 >= textParameters.Length)
{
//if we are out of textboxes, we are done.
break;
}
else
{
//move on to the next textbox. The loop begins again with new specifications set for the textbox.
textBoxIndex++;
}
}
}
squidingtons.Dispose();
drawBrush.Dispose();
drawFont.Dispose();
}