char command = ' '; int[] args = null; Point initPoint = new Point(); //Initial point of the subpath Point endPoint = new Point(); //End point of the (previous) command Point currentPoint = new Point(); //Current point of the command Point point = new Point(); //Parsing variable GraphicsPath path = new GraphicsPath(); ListNote that the points translation and scale were also taken from SVG and are used to displace the path points.points = new List (); var functions = Regex.Split(data, @"(?=[A-Za-z])").Where(c => c.HasValue()); foreach (string function in functions) { command = function[0]; args = Regex.Split(function.Remove(0, 1), @"[\s,]|(?=-)").Where(c => c.HasValue()).Select(c => c.ToInt()).ToArray(); switch (command) { case 'M': case 'm': //Open subpath initPoint = new Point { X = (char.IsUpper(command) ? translation.X : currentPoint.X) + args[0] * scale.X, Y = (char.IsUpper(command) ? translation.Y : currentPoint.Y) + args[1] * scale.Y }; endPoint = initPoint; currentPoint = initPoint; break; case 'Z': case 'z': path.CloseFigure(); currentPoint = initPoint; //Init point becomes the current point break; case 'C': case 'c': points.Clear(); points.Add(endPoint); int n = 0; for (int i = 0; i < args.Length; i += 2) { point = new Point { X = (char.IsUpper(command) ? translation.X : currentPoint.X) + args[i] * scale.X, Y = (char.IsUpper(command) ? translation.Y : currentPoint.Y) + args[i + 1] * scale.Y }; points.Add(point); if (++n >= 3) { //Not a control point currentPoint = point; endPoint = point; n = 0; } } path.AddBeziers(points.ToArray()); break; case 'L': case 'l': points.Clear(); points.Add(endPoint); for (int i = 0; i < args.Length; i += 2) { point = new Point { X = (char.IsUpper(command) ? translation.X : currentPoint.X) + args[i] * scale.X, Y = (char.IsUpper(command) ? translation.Y : currentPoint.Y) + args[i + 1] * scale.Y }; points.Add(point); currentPoint = point; } endPoint = currentPoint; path.AddLines(points.ToArray()); break; } }
21 March 2013
C# - Convert an SVG path to a GraphicsPath
The following algorithm takes the data string of an SVG path and converts it to a GDI+ GraphicsPath.
C# - Call Potrace and pass it a bitmap from code
The following snippet calls Potrace — a tool that converts raster images to vector images — and returns an SVG-string, without creating any files in between. I use this one in a drawing application I'm working on.
Process potrace = new Process { StartInfo = new ProcessStartInfo { FileName = "potrace.exe", Arguments = "-s -u 1", //SVG RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = Program.IsDebug, UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }, EnableRaisingEvents = false }; StringBuilder svgBuilder = new StringBuilder(); potrace.OutputDataReceived += (object sender2, DataReceivedEventArgs e2) => { svgBuilder.AppendLine(e2.Data); }; if (Program.IsDebug) { potrace.ErrorDataReceived += (object sender2, DataReceivedEventArgs e2) => { Console.WriteLine("Error: " + e2.Data); }; } potrace.Start(); potrace.BeginOutputReadLine(); if (Program.IsDebug) { potrace.BeginErrorReadLine(); } BinaryWriter writer = new BinaryWriter(potrace.StandardInput.BaseStream); bitmap.Save(writer.BaseStream, ImageFormat.Bmp); potrace.StandardInput.WriteLine(); //Without this line the input to Potrace won't go through. potrace.WaitForExit();
Subscribe to:
Posts (Atom)