我意识到这是一个非常具体的问题,但我对SVG和telerik都知之甚少,所以就这么说了。
我正在尝试将RadHtmlChart转换为C#中的图像。首先获得图表的svg我使用内置的telerik功能。
var chartRendering = $find("<%=BarChart.ClientID %>").getSVGString();
一旦我在服务器上有该字符串,我就会尝试将其转换为代表图像的Memory流。为此,我使用https://github.com/vvvv/SVG
XmlDocument xml = new XmlDocument();
xml.LoadXml(svgText);
SvgDocument svg = SvgDocument.Open(xml);
// Convert SVG document containing image to Stream
MemoryStream imageStream = new MemoryStream();
svg.Draw().Save(imageStream, ImageFormat.Png);
最后一行是代码中断并给出错误:设置的ColorBlend对象无效。 Position的最后一个元素必须等于1.0。 必须使用相同数量的位置和颜色值构造ColorBlend对象。 位置必须介于0.0和1.0之间,1.0表示数组中的最后一个元素。
奇怪的是,这只发生在一些图表而不是其他图表上。我注意到在一个特定的图表上,如果图表为10或更多x值,那么它是好的。但如果少于10个值则会中断。我也尝试使用temperorary文件将svg和图像存储到相同的结果。
我的想法已经用完了所以有人有建议吗?也许是从svg到c#中的图像的另一种方式。我已经看过inkscape但我无法使用它,因为它需要在服务器上安装为.exe。
编辑: 我找到了使用javascript的可能解决方案。不会对我有用,因为它使用了HTML5的canvas元素,我需要在IE8中使用它,但万一其他人偶然发现这个问题。 Convert SVG to image (JPEG, PNG, etc.) in the browser
解: 我决定为所有支持HTML5的浏览器和IE8的inkscape方法实现上面显示的javascript方法。
答案 0 :(得分:2)
我只是偶然发现了同样的问题。首先,我尝试从该项目的主干更新到最新的代码,但这并没有解决问题。
问题出在函数protected ColorBlend GetColorBlend(ISvgRenderer renderer, float opacity, bool radial)
该函数生成一个ColorBlend
对象,其中Positions
数组的最后一个元素有时不是1.0,但例如1.00000012或0.99999994。这会导致以下行中的SVGProject / Painting / SvgGradientServer.cs GetBrush
出现异常:
InterpolationColors = CalculateColorBlend(renderer, opacity, points[0],
effectiveStart, points[1], effectiveEnd),
问题可能是浮点值的舍入误差。我没有进一步分析它,只是添加了一个检查,修复了Positions
数组的最后一个元素。这对我有用。