System.Drawing.Graphics.DrawString - “参数无效” 例外
有时,微软的异常消息毫无帮助,令人恼火。 我创建了一个很好的 MVC 小方法来渲染文本。 方法主体如下。 当它到达“DrawString”方法时,我收到一个异常,提示“参数无效”。
请注意,据我所知,字体的构造正确(我只是使用 10pt 的 Arial),矩形大小为正且看起来有效,画笔是白色 SolidBrush,格式标志不会影响输出;即如果我从调用中排除格式标志,我仍然会收到错误,
DrawString 调用就在底部附近。
public ActionResult RenderText(
string fontFamily,
float pointSize,
string foreColor,
string backColor,
bool isBold,
bool isItalic,
bool isVertical,
string align,
string[] allText,
int textIndex)
{
// method renders a horizontal or vertical text image, taking all the text strings that will be rendered in each image
// and sizing the final bitmap according to which text would take the most space, thereby making it possible to render
// a selection of text images all at the same size.
Response.ContentType = "image/png";
var fmt = StringFormat.GenericTypographic;
if(isVertical)
fmt.FormatFlags = StringFormatFlags.DirectionVertical;
Func<string,StringAlignment> getAlign = (s => {
switch(s.ToLower())
{
case "right": return StringAlignment.Far;
case "center": return StringAlignment.Center;
default: return StringAlignment.Near;
}
});
fmt.LineAlignment = isVertical ? StringAlignment.Center : getAlign(align);
fmt.Alignment = isVertical ? getAlign(align) : StringAlignment.Center;
var strings = (allText ?? new string[0]).Where(t => t.Length > 0).ToList();
if(strings.Count == 0)
strings.Add("[Missing Text]");
FontStyle style = FontStyle.Regular;
if(isBold)
if(isItalic)
style = FontStyle.Bold | FontStyle.Italic;
else
style = FontStyle.Bold;
else if(isItalic)
style = FontStyle.Italic;
Font font = new Font(fontFamily, pointSize, style, GraphicsUnit.Point);
Color fc = foreColor.IsHexColorString() ? foreColor.ToColorFromHex() : foreColor.ToColor();
Color bc = backColor.IsHexColorString() ? backColor.ToColorFromHex() : backColor.ToColor();
var maxSize = new Size(0,0);
using(var tmp = new Bitmap(100, 200))
using(var gfx = Graphics.FromImage(tmp))
foreach(var txt in strings)
{
var size = gfx.MeasureString(txt, font, 1000, fmt);
maxSize = new Size(
Math.Max(Convert.ToInt32(isVertical ? size.Height : size.Width), maxSize.Width),
Math.Max(Convert.ToInt32(isVertical ? size.Width : size.Height), maxSize.Width)
);
}
using(var bmp = new Bitmap(maxSize.Width, maxSize.Height))
{
using(var gfx = Graphics.FromImage(bmp))
{
gfx.CompositingMode = CompositingMode.SourceCopy;
gfx.CompositingQuality = CompositingQuality.HighQuality;
gfx.SmoothingMode = SmoothingMode.HighQuality;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
var rect = new RectangleF(new PointF(0,0), maxSize);
gfx.FillRectangle(new SolidBrush(bc), rect);
gfx.DrawString(strings[textIndex], font, new SolidBrush(fc), rect, fmt);
}
bmp.Save(Response.OutputStream, ImageFormat.Png);
}
return new EmptyResult();
}
Sometimes Microsoft's exception messages are infuriatingly unhelpful. I have created a nice little MVC method to render text. The method body is below. When it reaches the "DrawString" method, I get an exception thrown saying "Parameter is not valid".
Note that the font, as best I can tell is constructed properly (I"m just using Arial at 10pt), the rect size is positive and valid looking, the brush is a white SolidBrush and the format flags do not affect the output; i.e. if I exclude the format flags from the call, I still get an error.
The DrawString call is right near the bottom.
public ActionResult RenderText(
string fontFamily,
float pointSize,
string foreColor,
string backColor,
bool isBold,
bool isItalic,
bool isVertical,
string align,
string[] allText,
int textIndex)
{
// method renders a horizontal or vertical text image, taking all the text strings that will be rendered in each image
// and sizing the final bitmap according to which text would take the most space, thereby making it possible to render
// a selection of text images all at the same size.
Response.ContentType = "image/png";
var fmt = StringFormat.GenericTypographic;
if(isVertical)
fmt.FormatFlags = StringFormatFlags.DirectionVertical;
Func<string,StringAlignment> getAlign = (s => {
switch(s.ToLower())
{
case "right": return StringAlignment.Far;
case "center": return StringAlignment.Center;
default: return StringAlignment.Near;
}
});
fmt.LineAlignment = isVertical ? StringAlignment.Center : getAlign(align);
fmt.Alignment = isVertical ? getAlign(align) : StringAlignment.Center;
var strings = (allText ?? new string[0]).Where(t => t.Length > 0).ToList();
if(strings.Count == 0)
strings.Add("[Missing Text]");
FontStyle style = FontStyle.Regular;
if(isBold)
if(isItalic)
style = FontStyle.Bold | FontStyle.Italic;
else
style = FontStyle.Bold;
else if(isItalic)
style = FontStyle.Italic;
Font font = new Font(fontFamily, pointSize, style, GraphicsUnit.Point);
Color fc = foreColor.IsHexColorString() ? foreColor.ToColorFromHex() : foreColor.ToColor();
Color bc = backColor.IsHexColorString() ? backColor.ToColorFromHex() : backColor.ToColor();
var maxSize = new Size(0,0);
using(var tmp = new Bitmap(100, 200))
using(var gfx = Graphics.FromImage(tmp))
foreach(var txt in strings)
{
var size = gfx.MeasureString(txt, font, 1000, fmt);
maxSize = new Size(
Math.Max(Convert.ToInt32(isVertical ? size.Height : size.Width), maxSize.Width),
Math.Max(Convert.ToInt32(isVertical ? size.Width : size.Height), maxSize.Width)
);
}
using(var bmp = new Bitmap(maxSize.Width, maxSize.Height))
{
using(var gfx = Graphics.FromImage(bmp))
{
gfx.CompositingMode = CompositingMode.SourceCopy;
gfx.CompositingQuality = CompositingQuality.HighQuality;
gfx.SmoothingMode = SmoothingMode.HighQuality;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
var rect = new RectangleF(new PointF(0,0), maxSize);
gfx.FillRectangle(new SolidBrush(bc), rect);
gfx.DrawString(strings[textIndex], font, new SolidBrush(fc), rect, fmt);
}
bmp.Save(Response.OutputStream, ImageFormat.Png);
}
return new EmptyResult();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我找到了问题的原因。 非常晦涩难懂的东西。 当我删除这一行时,代码有效:
Well I found out the cause of the problem. Something very obscure. The code works when I remove this line:
在调试时有帮助的是使方法更小。 例如,您可以替换
为
and
它使您的代码更具可读性,并且其他人更容易帮助您。
真的没有冒犯的意思!
亲切的问候,
安斯·弗鲁格
What could help while debugging, is making the methods smaller. For example, you could replace
by
and
It makes your code more readable and it makes it more easy for others to help you.
Really no offense meant!
Kind regards,
Ans Vlug