2016-05-01 7 views
1

Ich verwende die Microsoft Cognitive Services/Vision-API in meiner Anwendung.C# ColorTranslator.FromHtml() löst Ausnahme für "Gray" aus (ist kein gültiger Wert für Int32)

Vision API gibt Farben als Zeichenfolge zurück - entweder HEX (ohne das Präfix "#") oder als Name.

Um dies zu einer System.Drawing.Color zu konvertieren, die ich als Panel Hintergrundfarbe verwenden können, verwende ich den Code unten:

// Hex Color Format 
Regex hex = new Regex("^#(?:[0-9a-fA-F]{3}){1,2}$"); 

// Colours 
System.Drawing.Color accent = new System.Drawing.Color(); 
System.Drawing.Color fore = new System.Drawing.Color(); 
System.Drawing.Color back = new System.Drawing.Color(); 

try 
{ 
    if (hex.IsMatch("#" + result.Color.AccentColor.ToString())) accent = ColorTranslator.FromHtml("#" + result.Color.AccentColor.ToString()); 
    else accent = ColorTranslator.FromHtml(result.Color.AccentColor.ToString()); 

    fore = ColorTranslator.FromHtml(result.Color.DominantColorForeground.ToString()); 
    back = ColorTranslator.FromHtml(result.Color.DominantColorBackground.ToString()); 

    displayData.Colors = new System.Drawing.Color[] { accent, fore, back }; 

} 
catch (Exception e) 
{ 
    throw new Exception(e.Message.ToString()); 
} 

Das in 99% der Fälle gut, gearbeitet hat wenn jedoch eine der Farben kehrt von Micrsoft Vision-API mit „Gray“, erhalte ich eine Ausnahme:

Grey is not a valid value for Int32

(Dies ist der einzige Farbe, Name, den ich je gesehen habe, aber ich weiß nicht, wenn da werden andere würden)

Von meinem Verständnis wäre dies, weil „Gray“ kein HTML Farbe Name ist, wie es „Gray“ („Grau“ ist der CSS-Name) sollte http://www.rapidtables.com/web/color/gray-color.htm

Was würde der beste Weg, um diese Ausnahme zu behandeln? Ich habe mir überlegt, ein Lexikon für "schlechte" Farbnamen zu erstellen und diesen Farben ihren wahren HTML-Farbnamen (oder eine System.Drawing.Color) direkt zuzuordnen, aber dies scheint anfällig für menschliche Fehler und ein konstantes Spiel der Farbaktualisierung.

Gedanken? Vielen Dank.

+2

Wie Sie erwähnt haben, 99% der Fälle arbeiten. Also ein wenig "hard-code" für schlechte Farbnamen ist in Ordnung. P. S., Grey und Grey sind beide korrekt, einer ist Amerikaner, der andere ist Brite. – kennyzx

+0

Danke! Ja ich dachte, es wäre die einfachste Lösung, aber mochte nicht, wie chaotisch es könnte lol :) KISS-Lösung ist es! (es sei denn, jemand kann eine bessere Option bieten;)) –

Antwort

0

ich wahrscheinlich tat dies in einer gewundenen Weise, aber ich fusionierte alle Ihre Antworten in ein und ich glaube, es war eine saubere Lösung:

I Erstellen Sie eine neue Klasse mit dem Namen ColorFix, die nach "schlechten" Namen in einem Dictionary<string, string> (manuell definiert) sucht, dann überprüft, ob es ein KnownName ist, bevor andernfalls nur ein neues leeres Color Objekt zurückgegeben wird.

Dann erstellte ich aus der aufrufenden Klasse eine Methode ColorFromString, die die rohe Zeichenfolge Farbe aus der Microsoft-API akzeptiert.

Dies ist der alte Code, der versucht, ColorTranslate.FromHtml - und fängt Ausnahmen - außer jetzt Ausnahmen werden über ColorFix verarbeitet.

So rund um nur Parsing durch ein Dictionary und Überprüfen, ob es ein KnownName ist.

Ich bin relativ neu in C#, also hier ist mein Code, wenn dies jemand hilft:

Controller.cs

 // Colours 
     System.Drawing.Color accent = new System.Drawing.Color(); 
     System.Drawing.Color fore = new System.Drawing.Color(); 
     System.Drawing.Color back = new System.Drawing.Color(); 

     try 
     { 
      accent = ColorFromString(result.Color.AccentColor.ToString()); 
      fore = ColorFromString(result.Color.DominantColorForeground.ToString()); 
      back = ColorFromString(result.Color.DominantColorBackground.ToString()); 

      displayData.Colors = new System.Drawing.Color[] { accent, fore, back }; 
     } 
     catch (Exception e) 
     { 
      throw new Exception(e.Message.ToString()); 
     } 

...

private System.Drawing.Color ColorFromString(string color) 
    { 
     System.Drawing.Color value = new System.Drawing.Color(); 

     // Hex Color Format 
     Regex hex = new Regex("^#(?:[0-9a-fA-F]{3}){1,2}$"); 

     try 
     { 
      if (hex.IsMatch("#" + color)) value = ColorTranslator.FromHtml("#" + color); 
      else value = ColorTranslator.FromHtml(color); 
     } 
     catch (Exception) 
     { 
      ColorFix colorFix = new ColorFix(color); 

      value = colorFix.Fix(); 
     } 

     return value; 
    } 

ColorFix.cs

using System; 
using System.Collections.Generic; 
using System.Drawing; 

namespace Project.Services 
{ 
    class ColorFix 
    { 
     private string color; 
     public Dictionary<string, string> badColors = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); 

     // 
     // Constructor, takes Color String 
     // 
     // @param string(color) 
     // @return void 
     // 
     public ColorFix(string color) 
     { 
      this.color = color; 

      badColors.Add("Grey", "Gray"); 
     } 

     // 
     // Fix the Color Exception 
     // 
     // @return Color 
     // 
     public Color Fix() 
     { 
      if (Bad() != null) return (Color)Bad(); 
      if (Known() != null) return (Color)Known(); 

      return new Color(); 
     } 

     // 
     // Check if Color is a system KnownColor 
     // 
     // @return Nullable<Color> 
     // 
     private Color? Known() 
     { 
      string colorLower = color.ToLower(); 

      Array colorValues = Enum.GetValues(typeof(KnownColor)); 
      string[] colorNames = Enum.GetNames(typeof(KnownColor)); 

      for (int c = 0; c < colorValues.Length; c++) 
      { 
       if (colorNames.Equals(colorLower)) return Color.FromKnownColor((KnownColor)colorValues.GetValue(c)); 
      } 

      return null; 
     } 

     // 
     // Check if Color is within the Bad Colors Dictionary 
     // 
     // @return Nullable<Color> 
     // 
     private Color? Bad() 
     { 
      if (badColors.ContainsKey(color)) 
      { 
       try 
       { 
        return ColorTranslator.FromHtml(badColors[color]); 
       } 
       catch (Exception) 
       { 
        return null; 
       } 
      } 

      return null; 
     } 
    } 
} 
1

Setzen Sie einen try/catch-Block um den Code, der den Fehler verursacht, und wenn der Ausnahmetyp mit dem Ausnahmetyp übereinstimmt, den Sie erhalten, dann behandeln Sie ihn und passen Sie den Farbnamen an, anstatt die Ausnahme auszulösen.

+0

Ich weiß genau, was die Ausnahme ist (denke ich) - dass "Gray" ist kein HTML-Farbname - aber ich würde diese Methode verwenden, um eine Fallback-Farbe zu erstellen oder eine abschließende manuelle Konvertierungsfunktion. Vielen Dank! –

+0

Ah Ich schaute nur auf MSDN und sehen, dass es nicht einmal einen bestimmten Typ von Ausnahme auslöst. Klingt nach harter Codierung, das ist der Weg des geringsten Widerstands. –

+0

Ja, es ist nur eine schlechte Zeichenfolge, also kein bestimmter Typ :( –

2

Sie können wie folgt tun:

string ColorValue="your Color String"; 
      Color col; 
      try 
      { 
       col = ColorTranslator.FromHtml(ColorValue); 


      } 
      catch 
      { 
       ColorValue = ColorValue.ToLower(); 
       Array Colors=Enum.GetValues(typeof(KnownColor)); 
       string[] names=Enum.GetNames(typeof(KnownColor)); 
       for (int k = 0; k < Colors.Length; k++) 
       { 
        if (names.Equals(ColorValue)) 
        { 

         col = Color.FromKnownColor((KnownColor)Colors.GetValue(k)); 
        } 


       } 
      } 
     } 
+0

Leider "Grau" ist keine KnownColor, wie "Grau" ist die bekannte Rechtschreibung, aber danke :) –

Verwandte Themen