SVG 是使用 XML 来描述二维图形和绘图程序的语言。
SVG文件包含的形状如下:
用于路径的命令如下:
M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
A = elliptical Arc
Z = closepath
注释:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。
SVG文件基于xml,针对xml解析的python库较多,这里采用ElementTree进行解析。
Element 对象的常用属性:
解析流程如下:
将SVG文件传入ElementTree模块,获取xml树根。
先获取SVG图形宽高。
对xml树枝进行遍历,符合SVG图形的树枝,对于图形参数进行解析。
主函数如下:
def parser(svg_file):
tree = ET.parse(svg_file)
root = tree.getroot()
width = root.get('width')
height = root.get('height')
if len(width) == 0 or len(height) == 0:
print "width or height is 0"
exit(1)
if "mm" in width:
width = width[:-2]
if "mm" in height:
height = height[:-2]
print width, height
for elem in root.iter():
try:
_, tag_suffix = elem.tag.split('}')
except ValueError:
continue
if tag_suffix in svg_shapes:
tag_suffix = tag_suffix.capitalize()
print tag_suffix
shape_class = globals()[tag_suffix](elem)
图形解析以矩形为例,需要获取矩形的起始点及长宽:
class Rect:
def __init__(self, xml_node):
self.xml_node = xml_node
if self.xml_node is not None:
rect_el = self.xml_node
self.x = float(rect_el.get('x')) if rect_el.get('x') else 0
self.y = float(rect_el.get('y')) if rect_el.get('y') else 0
self.rx = float(rect_el.get('rx')) if rect_el.get('rx') else 0
self.ry = float(rect_el.get('ry')) if rect_el.get('ry') else 0
self.width = float(rect_el.get('width')) if rect_el.get('width') else 0
self.height = float(rect_el.get('height')) if rect_el.get('height') else 0
print("Rect: x=%f, y=%f, rx=%f, ry=%f, width=%f, height=%f"
% (self.x, self.y, self.rx, self.ry, self.width, self.height))
else:
self.x = self.y = self.rx = self.ry = self.width = self.height = 0
print("Rect: Unable to get the attributes for %s", self.xml_node)
完整代码及SVG文件可从github下载:
https://github.com/ai2robot/svg_parser