如何在不改变Win2D中的原始文件的情况下编辑.svg文件属性?

How to edit .svg file attribute without changing the original file in Win2D?

我正在使用 Win2D 开发 UWP 应用程序。我可以在 CanvasControl 中绘制 SVG,但我不知道如何编辑 .svg 文件的属性(xml 格式)?

我的代码:

    private async void DrawSVG(CanvasControl sender, CanvasDrawEventArgs args)
    {
        Uri localUri = new Uri("ms-appx:///Assets/like_icon.svg");

        CanvasSvgDocument svgDocument = null;

        GetImage().Wait();
        async Task GetImage()
        {
            await Task.Run(async () =>
            {
                var file = await StorageFile.GetFileFromApplicationUriAsync(localUri);
                IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
                svgDocument = await CanvasSvgDocument.LoadAsync(sender, stream);

            }).ConfigureAwait(false);
        }
        args.DrawingSession.DrawSvg(svgDocument, new Size(500, 500));
    }

like_icon.svg

<svg xmlns="http://www.w3.org/2000/svg" width="18" height="17" viewBox="0 0 18 17">
  <g fill="none" fill-rule="evenodd" transform="translate(.492 .27)">
    <path fill="#000000" d="M16.8477376,7.20815969 C16.8477376,6.35482636 16.1544043,5.66149302 15.3028487,5.66149302 L11.7526265,5.61171525 L12.0797376,2.99304858 C12.0797376,2.10949302 11.5001821,0.824159691 10.5899598,0.824159691 L9.62107095,0.824159691 L9.12684872,3.46060414 L6.8886265,6.9272708 C6.65040428,7.25971525 6.48151539,7.53704858 6.35884872,7.78593747 C6.15084872,7.55660414 5.8486265,7.41082636 5.5126265,7.41082636 L1.9926265,7.41082636 C1.36151539,7.41082636 0.847737612,7.92282636 0.847737612,8.55393747 L0.847737612,13.9797152 C0.847737612,14.6108264 1.36151539,15.1246041 1.9926265,15.1246041 L5.5126265,15.1246041 C5.9766265,15.1246041 6.3766265,14.845493 6.55618206,14.4490486 C6.89751539,14.8117152 7.38107095,15.0410486 7.91973761,15.0410486 L13.7437376,15.0410486 C14.5952932,15.0410486 15.2886265,14.3477152 15.2886265,13.4961597 C15.2886265,13.3023819 15.2548487,13.117493 15.1855154,12.941493 C15.8432932,12.7548264 16.3108487,12.1468264 16.3108487,11.453493 C16.3108487,11.2117152 16.2521821,10.9717152 16.1419598,10.7566041 C16.5792932,10.4703819 16.8477376,9.9832708 16.8477376,9.46060414 C16.8477376,9.03038191 16.6699598,8.62504858 16.3570709,8.3352708 C16.6699598,8.04371525 16.8477376,7.63838191 16.8477376,7.20815969 Z"/>
    <path fill="#FFFFFF" fill-rule="nonzero" d="M12.5758817,3.05502449 L12.5797376,2.99304858 C12.5797376,1.71035442 11.7493049,0.324159691 10.5899598,0.324159691 L9.20609061,0.324159691 L8.65350851,3.27192682 L6.46857,6.65606509 C6.36891464,6.79470655 6.27802307,6.92907635 6.19575641,7.0594942 C5.98490385,6.96298269 5.75270082,6.91082636 5.5126265,6.91082636 L1.9926265,6.91082636 C1.08527398,6.91082636 0.347737612,7.64678172 0.347737612,8.55393747 L0.347737612,13.9797152 C0.347737612,14.8869687 1.08537301,15.6246041 1.9926265,15.6246041 L5.5126265,15.6246041 C5.94542749,15.6246041 6.34800042,15.4544786 6.64702124,15.1691882 C7.02157239,15.4085728 7.46024807,15.5410486 7.91973761,15.5410486 L13.7437376,15.5410486 C14.8714355,15.5410486 15.7886265,14.6238576 15.7886265,13.4961597 C15.7886265,13.4075077 15.7831854,13.3200468 15.7722711,13.2338957 C16.4007963,12.8765926 16.8108487,12.2009061 16.8108487,11.453493 C16.8108487,11.2714304 16.7859185,11.090129 16.737515,10.9150293 C17.1230885,10.5338146 17.3477376,10.011585 17.3477376,9.46060414 C17.3477376,9.05510266 17.2281107,8.66486371 17.0086874,8.33470398 C17.2281277,8.00387435 17.3477376,7.61363299 17.3477376,7.20815969 C17.3477376,6.07904816 16.4309107,5.16149302 15.3028487,5.16149302 L12.3179849,5.11960075 L12.5758817,3.05502449 Z M10.5899598,1.32415969 C11.0548864,1.32415969 11.5671284,2.16978607 11.5795087,2.96377345 L11.1872671,6.10383747 L15.2958389,6.16144388 C15.8784481,6.16149302 16.3477376,6.63115526 16.3477376,7.20815969 C16.3477376,7.49835728 16.2285488,7.77160392 16.0162081,7.96946682 L15.6224358,8.33639106 L16.0173254,8.70211265 C16.2286683,8.89784505 16.3477376,9.17050104 16.3477376,9.46060414 C16.3477376,9.81164448 16.166826,10.1427655 15.8681519,10.3382392 L15.4919378,10.5844607 L15.6969746,10.9846131 C15.7715125,11.1300824 15.8108487,11.2920369 15.8108487,11.453493 C15.8108487,11.9190842 15.4957464,12.333711 15.0490135,12.4604865 L14.5179941,12.6111812 L14.7203112,13.1247553 C14.7659401,13.2405825 14.7886265,13.363148 14.7886265,13.4961597 C14.7886265,14.0715729 14.3191508,14.5410486 13.7437376,14.5410486 L7.91973761,14.5410486 C7.53698999,14.5410486 7.17998941,14.3823053 6.92028205,14.1063662 L6.4086865,13.562796 L6.10071945,14.2427628 C5.99653164,14.4728012 5.76698985,14.6246041 5.5126265,14.6246041 L1.9926265,14.6246041 C1.63765776,14.6246041 1.34773761,14.334684 1.34773761,13.9797152 L1.34773761,8.55393747 C1.34773761,8.19954742 1.63707892,7.91082636 1.9926265,7.91082636 L5.5126265,7.91082636 C5.69634128,7.91082636 5.86751631,7.98846457 5.98848921,8.12184494 L6.48235393,8.66636246 L6.80733637,8.00697781 C6.92034857,7.7776777 7.07772278,7.52179443 7.29505221,7.21850634 L9.54690522,3.73180985 L9.60018894,3.64928145 L10.0360513,1.32415969 L10.5899598,1.32415969 Z"/>
  </g>
</svg>

在此 .svg 中,我想在运行时更改 path 元素下的 fill 属性。它在原始 .svg 文件中是黑色的,我想在运行时根据我的情况更改颜色。

注意:我不想编辑和保存.svg文件,我只想编辑流对象。怎么做到的?

基于 CanvasSvgDocument 的 document,我们注意到 CanvasSvgDocument 具有 LoadElementAsync 属性,它可以从包含 XML 片段的流中加载 SVG 元素。所以我们可以用它来获取svg文件的结构。然后找到我们要改变的路径元素,调用SetStringAttribute方法改变填充的颜色属性。最后,我们将根元素分配给 CanvasSvgDocument。例如:

private void CanvasControl_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
    Uri localUri = new Uri("ms-appx:///Assets/like_icon.svg");

    CanvasSvgDocument svgDocument = null;

    GetImage().Wait();
    async Task GetImage()
    {
        await Task.Run(async () =>
        {    
            var file = await StorageFile.GetFileFromApplicationUriAsync(localUri);
            IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);

            svgDocument = new CanvasSvgDocument(sender);
            CanvasSvgNamedElement element = await svgDocument.LoadElementAsync(stream);
                
            CanvasSvgNamedElement gChild = element.FirstChild as CanvasSvgNamedElement;
            CanvasSvgNamedElement BlackPath = gChild.FirstChild as CanvasSvgNamedElement;
            BlackPath.SetStringAttribute("fill", "#DC143C");
            svgDocument.Root.AppendChild(element);

        }).ConfigureAwait(false);
    }

    args.DrawingSession.DrawSvg(svgDocument, new Size(500, 500));
}