如何将SVG图像渲染为单色位图图像?

时间:2018-08-27 14:31:14

标签: c# .net svg bitmap

使用SVG.NET NuGet包将SVG图像渲染为.NET中的位图图像,我正在尝试在渲染过程中更改图像的颜色。

例如我有这个源SVG图片:

enter image description here

并要渲染它,例如作为绿色的位图图像:

enter image description here

(在我的情况下,所有源SVG图像都是单色的。)

我当前的未成功代码如下:

var svgDoc = SvgDocument.Open<SvgDocument>(svgFilePath, null);

// Tried several things, all without any changes in the resulting bitmap:
svgDoc.Color = new SvgColourServer(Color.DarkGreen);
svgDoc.StopColor = new SvgColourServer(Color.DarkGreen);
svgDoc.Stroke = new SvgColourServer(Color.DarkGreen);
svgDoc.Fill = new SvgColourServer(Color.DarkGreen);

var bitmap = svgDoc.Draw();

我还签出了源代码并仔细检查了一下,但仍然找不到改变颜色的方法。

我的问题:

如何在通过SVG.NET将SVG图像渲染为位图图像期间更改颜色?

(我在SO上不仅在他们的GitHub页面上询问,因为似乎作者根本没有对questions做出回应,也很少很少回应)

更新1:

起作用的是以下片段:

var svgDoc = SvgDocument.Open<SvgDocument>(svgFilePath, null);

// Recursively change all nodes.
processNodes(svgDoc.Descendants(), new SvgColourServer(Color.DarkGreen));

var bitmap = svgDoc.Draw();

与此功能一起:

private void processNodes(IEnumerable<SvgElement> nodes, SvgPaintServer colorServer)
{
    foreach (var node in nodes)
    {
        if (node.Fill != SvgPaintServer.None) node.Fill = colorServer;
        if (node.Color != SvgPaintServer.None) node.Color = colorServer;
        if (node.StopColor != SvgPaintServer.None) node.StopColor = colorServer;
        if (node.Stroke != SvgPaintServer.None) node.Stroke = colorServer;

        processNodes(node.Descendants(), colorServer);
    }
}

尽管我不确定所有节点的递归迭代的成本以及是否有更快的方法。

1 个答案:

答案 0 :(得分:1)

您的第一次尝试失败是合理的,因为您仅在父fill元素上设置了stroke<svg>,并且父项的填充/描边不会覆盖子项的填充/行程。示例:

<svg fill="green" stroke="green" xmlns="http://www.w3.org/2000/svg" width="200" height="200" >
    <g stroke="black" stroke-width="2" fill="none" >
        <path d="M90,90 v-80 a80,80 0 0,0 -80,80 z" fill="red" />
        <path d="M100,100 h-80 a80,80 0 1,0 80,-80 z" fill="gold" />
    </g>
</svg>

更新方法的一种替代方法是通过CSS设置填充/描边,因为CSS会覆盖任何fillstroke属性。因此,如果 SVG.NET 允许您在SVG中插入/编辑<style>元素,则可以执行以下操作:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" >
    <style>
        * {
            fill: green;
            stroke: green;
        }
    </style>
    <g stroke="black" stroke-width="2" fill="none" >
        <path d="M90,90 v-80 a80,80 0 0,0 -80,80 z" fill="red" />
        <path d="M100,100 h-80 a80,80 0 1,0 80,-80 z" fill="gold" />
    </g>
</svg>