2

I am trying to save InkCanvas , InkStorkes as a SVG. I found a previous question that works for Wpf,but I have been unable to get it to work with uwp. Wpf InkCanvas save stokes as svg . I made some changes to it, but I am running into issues with GetGrometry and XamlWriter.

 var svg = new SvgDocument();
        var colorServer = new SvgColourServer(System.Drawing.Color.Black);

        var group = new SvgGroup { Fill = colorServer, Stroke = colorServer };
        svg.Children.Add(group);

        foreach (var stroke in inkCanvas.InkPresenter.StrokeContainer.GetStrokes())
        {

            var geometry = stroke.GetGeometry(stroke.DrawingAttributes).GetOutlinedPath‌​Geometry();

            var s = XamlWriter.Save(geometry);

            if (s.IsNotNullOrEmpty())
            {
                var element = XElement.Parse(s);

                var data = element.Attribute("Figures")?.Value;

                if (data.IsNotNullOrEmpty())
                {
                    group.Children.Add(new SvgPath
                    {
                        PathData = SvgPathBuilder.Parse(data),
                        Fill = colorServer,
                        Stroke = colorServer
                    });
                }
            }
        }
Question
  • 171
  • 1
  • 14
  • 1
    In UWP, GIF is the only file format supported for saving ink data. So, you could not save ink strokes into svg file directly. You could think about convert the ink strokes into Win2D geometry (using [CanvasGeometry.CreateInk](https://microsoft.github.io/Win2D/html/Overload_Microsoft_Graphics_Canvas_Geometry_CanvasGeometry_CreateInk.htm)), and using [CanvasSvgDocument](https://microsoft.github.io/Win2D/html/Methods_T_Microsoft_Graphics_Canvas_Svg_CanvasSvgDocument.htm) relevant APIs to get your target. – Xie Steven Jul 17 '17 at 08:47
  • @XavierXie-MSFT , Thanks I was able to use CanvasGeometry.CreateInk, now I have a CanvasGeometry object, but how do convert it to a SVG using CanvasSvgDocument? – Question Jul 18 '17 at 16:13
  • You could use any of the CanvasGeometry methods to query information about the path. For example, `canvasGeometry.SendPathTo`, you could define your custom path reader class which has implemented `ICanvasPathReceiver`(check [win2d sample](https://github.com/Microsoft/Win2D-Samples/blob/241f16699440877749285bbab30b28002d2f263c/ExampleGallery/Shared/CustomTextLayouts.xaml.cs#L244)). Then, you would get all path information, you could create svg path by the path imformation. Please read the [svg path syntax](https://www.w3schools.com/graphics/svg_path.asp) – Xie Steven Jul 19 '17 at 02:48
  • After you've created svg path, you could use `CanvasSvgDocument.LoadFromXml(sender, "")` method to load it and use `CanvasSvgDocument.SaveAsync(IRandomAccessStream stream)` method to save it into a file stream. – Xie Steven Jul 19 '17 at 02:54

1 Answers1

-1

I implemented an approach from the comments Xavier Xie - MSFT.

The main idea was to use own implementation of ICanvasPathReceiver interface - here is CanvasGeometryToSvgPathReader class:

var svgDocument = new CanvasSvgDocument(canvasDevice);

foreach (var stroke in InkCanvas.InkPresenter.StrokeContainer.GetStrokes())
{
    var canvasGeometry = CanvasGeometry.CreateInk(drawingSession, new[] {stroke});

    var pathReceiver = new CanvasGeometryToSvgPathReader();
    canvasGeometry.SendPathTo(pathReceiver);

    var element = svgDocument.Root.CreateAndAppendNamedChildElement("path");

    element.SetStringAttribute("d", pathReceiver.Path);
    element.SetColorAttribute("fill", stroke.DrawingAttributes.Color);
}

As result ballpoint pen renders fine, highlighter worse and pencil doesn't render.

Full source code: https://github.com/ycherkes/InkToSvg

Yevhen Cherkes
  • 626
  • 7
  • 10
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes – L_J Jul 18 '18 at 09:49