2009-08-05 13 views
12

Czasami komunikaty o wyjątkach firmy Microsoft są irytująco pomocne. Stworzyłem fajną małą metodę MVC do renderowania tekstu. Ciało metody znajduje się poniżej. Gdy dojdzie do metody "DrawString", otrzymuję wyjątek zgłoszony, mówiąc "Parametr jest nieprawidłowy".System.Drawing.Graphics.DrawString - "Parametr nie jest poprawny" wyjątek

Zauważ, że czcionka, jak najlepiej potrafię powiedzieć, jest skonstruowana poprawnie (używam po prostu Arial po 10pt), rozmiar prostokąta jest dodatni i prawidłowy, pędzel jest białym bryłką, a flagi formatu nie wpływają wyjście, to znaczy, jeśli wykluczyć flagi format z wezwania, nadal pojawia się błąd

sznureczka Połączenie jest tuż przy dnie

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

Tylko uwaga: nowy SolidBrush (fc) będzie przeciekać zasób Brush, potrzebuje też przy użyciu bloku. –

+1

Tylko wskazówka: Miałem ten sam błąd "Parametr nie jest prawidłowy" i dotarłem do tego wątku. W moim przypadku nie miało to nic wspólnego z zaakceptowaną odpowiedzią, ponieważ przechodziłem do instancji DrawString a Disposed z czcionką lub pędzlem. Wyjątek nie jest naprawdę pomocny ... – AFract

Odpowiedz

14

Dobrze znalazłem przyczynę problemu... Coś bardzo niejasnego. Kod działa po usunięciu tej linii:

gfx.CompositingMode = CompositingMode.SourceCopy; 
+0

Life saver! To ma sens, jestem pewien, że trzeba włączyć mieszanie, aby narysować tekst, ale byłoby miło, gdyby komunikat o błędzie wspomniał coś o tym :-) – eodabash

4

To, co może pomóc podczas debugowania, powoduje, że metody są mniejsze. Na przykład, można zastąpić

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

przez

FontStyle style = GetFontStyle(isBold, isItalic); 

i

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

To sprawia, że ​​kod jest bardziej czytelny, a to sprawia, że ​​łatwiej dla innych, aby ci pomóc.

Naprawdę bez obrazy!

poważaniem, Ans Vlug

Powiązane problemy