My workaround to this problem was to make sure the color is always passed to Svg.Skia
as a known (named) color, because Svg.Skia
then seems to generate a valid SVG element.
ColorTranslator
is calling Color.FromArgb(int, int, int)
which will return an unnamed Color
, like "128, 64, 32"
. As pointed out in the comments already, due to a change in Svg.Skia
version 0.5.11, this RGB value will be used and a corrupt SVG element is created:
<path ... style="fill:0, 128, 64, 32;" />
However, if color is a known (named) Color
, then Svg.Skia
will insert a SVG element which seems to be valid:
<path ... style="fill:Red;" />
To support all possible colors, I calculate the closest known color, by using the code from this answer.
public static Color FromHtml(string htmlColor)
{
ArgumentException.ThrowIfNullOrEmpty(htmlColor);
var color = ColorTranslator.FromHtml(htmlColor);
var closestDistance = double.MaxValue;
var closest = Color.White;
var knownColors = Enum.GetValues<KnownColor>().Select(Color.FromKnownColor);
foreach (var knownColor in knownColors)
{
// Calculate Euclidean distance
var rDistSqrd = Math.Pow(color.R - knownColor.R, 2);
var gDistSqrd = Math.Pow(color.G - knownColor.G, 2);
var bDistSqrd = Math.Pow(color.B - knownColor.B, 2);
var distance = Math.Sqrt(rDistSqrd + gDistSqrd + bDistSqrd);
if (!(distance < closestDistance))
{
continue;
}
closestDistance = distance;
closest = knownColor;
}
if (!closest.IsNamedColor)
{
throw new ArgumentException("HTML color cannot be converted to a named color.", nameof(htmlColor));
}
return closest;
}
And tests:
[DataTestMethod]
[DataRow("#FFEBCD", KnownColor.BlanchedAlmond)]
[DataRow("#ffebcd", KnownColor.BlanchedAlmond)]
[DataRow("#ff6e6e", KnownColor.Salmon)]
[DataRow("#8ccbff", KnownColor.LightSkyBlue)]
[DataRow("#210ca5", KnownColor.DarkBlue)]
public void CanCallFromHtml(string htmlColor, KnownColor expected)
{
// Act
var knownColor = KnownColorHelper.FromHtml(htmlColor);
// Assert
Assert.AreEqual(Color.FromKnownColor(expected), knownColor);
}