Reputation: 57
I am working on a robotic project that from an Android running device take a picture then send to cloudconvert.org to convert it into an SVG, then all SVG paths will be translated into x y coordinates and serially send to the robotic arm which will plot them with the pen on or off.
So I've gone so far in this project and the only problem that I am having now is to parse the SVG file into a list of path as a list of string.
I tried minidom but it doesn't seems that it's working. I can actually access the SVG file and but I can't access the path data example 'M 100,200 L 200.300' instead of that I get
>>> from xml.dom import minidom
>>> xmldoc= minidom.parse("C:\Users\DELL\Desktop\drawing-1.svg")
>>> a=xmldoc.getElementsByTagName("svg")[0]
>>> b=a.getElementsByTagName("g")[0]
>>> pth=b.getElementsByTagName("path")[0]
>>> pth
<DOM Element: path at 0x1bb6238>
I just want to access the data inside that dom object as a string and when I tried
>>> print (str(pth))
nothing appears just two blank line then >>>
appears again.
Upvotes: 3
Views: 10656
Reputation: 81
I wrote my own solution: https://github.com/RaubCamaioni/svgpath
Initially, I was using svg.path but speed became an issue when trying to increase the resolution. Modifying svg.path was difficult. Lots of class inheritance. Iterating over svg.path objects to create a 2D path was clunky.
No classes in my solution. Should be easy to pick apart.
Uses pyparsing to parse the SVG paths: Parsing Expression Grammars (PEGs).
No need to parse the DOM.
# svg: https://pattern.monster/flower-7/
import svg_peg
import svg_symbols
with open("flower7.svg", "r") as f:
svg_string = f.read()
tree = svg_peg.parse(svg_string)
tokens = svg_symbols.tree_to_tokens(tree)
for path in svg_symbols.tokens_to_path(tokens):
plt.plot(path[:, 0], path[:, 1])
plt.show()
Upvotes: 0
Reputation: 2903
That's an old thread but since the link from the accepted answer no longer works here is my approach to processing svg paths.
There is an svg.path module which extracts paths and other shapes plus provides methods to process them.
from xml.dom import minidom
from svg.path import parse_path
svg_dom = minidom.parseString(svg_string)
path_strings = [path.getAttribute('d') for path in svg_dom.getElementsByTagName('path')]
for path_string in path_strings:
path_data = parse_path(path_string)
# now use methods provided by the path_data object
# e.g. points can be extracted using
# point = path_data.pos(pos_val)
# where pos_val is anything between 0 and 1
Upvotes: 8
Reputation: 36
I have been working on the same problem my solution was this: 1.convert svg paths to polygons using http://guilhermemussi.com/conversor.html 2. use a relatively simple python script to extract a list of the points. Here is my code it might be sort of messy/inneficient but it gets the job done
scribble=open("scrib1.txt")
for line in scribble:
if line.startswith("<polygon"):
rightline=line.split('"')
commas=rightline[13].split(' ')
newlist=[]
for i in commas:
tup=i.split(',')
newlist.append((tup[0],tup[1]))
Upvotes: 2