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

问题描述

我正在使用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文件的结构。然后找到我们要更改的path元素,并调用SetStringAttribute方法以更改fill属性的颜色。最后,我们将根元素分配给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));
}