2009-08-05 10 views
12

Manchmal Microsoft Exception-Nachrichten sind ärgerlich nicht hilfreich. Ich habe eine nette kleine MVC-Methode zum Rendern von Text erstellt. Der Methodenkörper ist unten. Wenn die Methode "DrawString" erreicht wird, wird eine Ausnahme ausgelöst, die besagt "Parameter ist nicht gültig".System.Drawing.Graphics.DrawString - "Parameter ist nicht gültig" Ausnahme

Beachten Sie, dass die Schriftart, wie ich am besten sagen kann, richtig konstruiert ist (ich verwende nur Arial bei 10pt), die richtige Größe ist positiv und gültig, der Pinsel ist ein weißer SolidBrush und die Formatflags nicht beeinflussen die Ausgabe, das heißt, wenn ich die Format-Flags aus dem Aufruf auszuschließen, erhalte ich noch einen Fehler

die DrawString Anruf direkt in der Nähe der Unterseite ist

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(); 
} 
+1

Nur ein Hinweis: neue SolidBrush (fc) eine Bürste Ressource Leck, es braucht einen zu verwenden Block. –

+1

Nur ein Tipp: Ich hatte den gleichen Fehler "Parameter ist nicht gültig" und kam auf diesen Thread. In meinem Fall hatte es nichts mit der akzeptierten Antwort zu tun, weil ich eine Disposed-Instanz von Font oder Pinsel an DrawString übergeben habe. Die Ausnahme ist nicht wirklich hilfreich ... – AFract

Antwort

14

Nun, ich fand die Ursache des Problems aus... Etwas sehr undurchsichtig Der Code funktioniert, wenn ich diese Zeile entferne:

gfx.CompositingMode = CompositingMode.SourceCopy; 
+0

Lebensretter! Das macht eigentlich Sinn, ich bin mir sicher, dass es Blending benötigt, um Text zu zeichnen, aber es wäre schön, wenn die Fehlermeldung etwas dazu sagen würde :-) – eodabash

4

Was beim Debuggen helfen könnte, ist, die Methoden zu verkleinern. Zum Beispiel könnten Sie

FontStyle style = FontStyle.Regular; 
if(isBold) 
    if(isItalic) 
     style = FontStyle.Bold | FontStyle.Italic; 
    else 
     style = FontStyle.Bold; 
else if(isItalic) 
    style = FontStyle.Italic; 

von

FontStyle style = GetFontStyle(isBold, isItalic); 

und

public FontStyle GetFontStyle(bool isBold, bool isItalic) 
{ 
    if(isBold) 
     if(isItalic) 
      return FontStyle.Bold | FontStyle.Italic; 
     else 
      return FontStyle.Bold; 
    else if(isItalic) 
     return FontStyle.Italic; 
    else 
     return FontStyle.Regular; 
} 

Es macht Ihr Code besser lesbar ersetzen und es macht es einfacher für andere, Ihnen zu helfen.

Wirklich nichts für ungut gemeint!

Mit freundlichen Grüßen, Ans Vlug

Verwandte Themen