Closed Ponant closed 7 years ago
After converting the ink to Win2D geometry, you can use any of the CanvasGeometry methods to query information about the path. This provides rich functionality for querying, hit testing, or reading back the path information.
Thanks. Could you be more specific? You say that any method would work but I do not see how to get the path yet. I assume you propose to start with this
var canvasGeometry = CanvasGeometry.CreateInk(device, strokes);
var bounds = canvasGeometry.ComputeBounds();
The only candidate I can see is the void method
canvasGeometry.SendPathTo
But I do not know how to populate the argument ICanvasPathReceiver
...
Depending what you are wanting to do with the path, you might want to use SendPathTo, or Tesselate, or ComputePointOnPath, or FillContainsPoint.
ICanvasPathReciever is an interface that is called by Win2D - you implement this yourself to do whatever you want with the path data.
I am converting the path to an svg path. I can do this without trouble when the pentip is a circle modulo any transform applied to it, but I am having troubles with the rectangle shape, so the solution is to be able to get the path and convert it to an svg path. Any insight or example would be welcomed.
SendPathTo is probably what you want for that.
Do you have any samples on this repo where can I get the logic behind the interface?
I believe it is used somewhere in Example Gallery.
OK thanks, hopefully I will be able to locate some code.
Hmm, after reflection and reading this answer by @clandrew https://github.com/Microsoft/Win2D/issues/232 , I think the SendPathTo will provide me with the basic stroke properties (cubic Bezier points, inkpoints position), whereas I would like to retrieve the outline path for a given stroke.
Are you looking for the "Outline" operation?
See InkExample in example gallery with "Dry Ink Rendering" set to Geometry for an example of how this looks.
@damyanp , the XAML equivalent is when you take a shape, you remove the fill but keep the border. I am looking at the same but with a stroke.
@damyanp , I think your proposal is what suits best. As a reminder, this sample has this piece of code:
var strokeStyle = new CanvasStrokeStyle { DashStyle = CanvasDashStyle.Dot };
var strokesGroupedByColor = from stroke in strokes
group stroke by stroke.DrawingAttributes.Color into strokesOfColor
select strokesOfColor;
foreach (var strokesOfColor in strokesGroupedByColor)
{
var geometry = CanvasGeometry.CreateInk(ds, strokesOfColor.ToList()).Outline();
ds.DrawGeometry(geometry, strokesOfColor.Key, 1, strokeStyle);
}
With this I can render the outline on a png file by using DrawGeometry. However, what I would like to do is to access the X,Y coordinates of each of the data points + Bezier points in this dashed outline, because these will then be manipulated later in my app. Any advice is welcomed and I should be able to fix it.
To get at the coordinates of the points on the path you need to use SendPathTo .
OK guys, thanks a lot I can make it work. I have a few questions on some obscure info in the docs and I we can close this issue.
1) The number of points that I get for the outline or for the stroke itself is much bigger than the number of points provided by InkCanvas (via GetInkPoints
and GetRenderingSegments
). This makes my SVG files quite big unfortunately. So I wonder if there no cleanup method that I can call. I tried
var geometry = CanvasGeometry.CreateInk(ds, strokes).Simplify(CanvasGeometrySimplification.CubicsAndLines).Outline();
and
var geometry = CanvasGeometry.CreateInk(ds, strokes).).Outline().Simplify(CanvasGeometrySimplification.CubicsAndLines);
but they seem to make no difference with respect to
var geometry = CanvasGeometry.CreateInk(ds, strokes).Outline()
2) I left AddQuadraticBezier
and AddArc
empty , because it seems to me that InCanvas nevers uses Quadratic Bezier and Arcs for strokes. Can you confirm, or else tell me in which pen settings they would appear?
3) What is flatteningTolerance
in the Outline method, and what is its range (<1?
) and default or recommended value?
4) Is there a simple explanation for CanvasFilledRegionDetermination
Winding vs Alternate?
5) CanvasFigureSegmentOptions.ForceUnstroked
???
Thanks
1) Win2D/D2D do not provide a general purpose geometry optimizer. The Simplify method simplifies the /type/ of geometry, replacing complex curve types with more restricted beziers or straight line segments, but it will not approximate multiple curves or lines with smaller numbers of shapes. If you need something like that you will have to build it yourself.
Note that the ink rendering implementation in Windows 10 is quite sophisticated and well optimized, so I'm not surprised that you may encounter size or speed problems when moving that same data across to some other more general purpose rendering technology.
2) What types of curve you get is an implementation detail that could change at any time. If you don't want to deal with these, use Simplify to get rid of them.
4) https://msdn.microsoft.com/en-us/library/windows/desktop/dd368110%28v=vs.85%29.aspx
5) Specifies that the segments of the figure will not appear stroked, for example, when drawn with DrawGeometry Overload.
@Ponant Could you please show me how to convert CanvasGeometry path to svg path? I've been troubled by this problem for a long time.
Hi, I have an InkCanvas where I draw strokes, and I would like to know if it is possible to extract the path which outlines the stroke by using Win2D. By outline, I mean the path boundary (not rect) in which the stroke is contained and filled. Here is a picture which hopefully is clear enough. The draw was made with a rectangle pentip with an angle but the pressure was set to Off for clarity. Thanks