add ability to preserve svg-attributes
Added svg_attributes attribute to wsvg and disvg. Added return_svg_attributes option to svg2paths. Added convenience function svg2paths2().pull/4/head
parent
0c682bf4d8
commit
15d186ff33
35
README.ipynb
35
README.ipynb
|
@ -86,7 +86,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 16,
|
"execution_count": 5,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": true
|
"collapsed": true
|
||||||
},
|
},
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 17,
|
"execution_count": 6,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 18,
|
"execution_count": 7,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 19,
|
"execution_count": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -244,6 +244,11 @@
|
||||||
"from svgpathtools import svg2paths, wsvg\n",
|
"from svgpathtools import svg2paths, wsvg\n",
|
||||||
"paths, attributes = svg2paths('test.svg')\n",
|
"paths, attributes = svg2paths('test.svg')\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"# Update: You can now also extract the svg-attributes by setting\n",
|
||||||
|
"# return_svg_attributes=True, or with the convenience function svg2paths2\n",
|
||||||
|
"from svgpathtools import svg2paths2\n",
|
||||||
|
"paths, attributes, svg_attributes = svg2paths2('test.svg')\n",
|
||||||
|
"\n",
|
||||||
"# Let's print out the first path object and the color it was in the SVG\n",
|
"# Let's print out the first path object and the color it was in the SVG\n",
|
||||||
"# We'll see it is composed of two CubicBezier objects and, in the SVG file it \n",
|
"# We'll see it is composed of two CubicBezier objects and, in the SVG file it \n",
|
||||||
"# came from, it was red\n",
|
"# came from, it was red\n",
|
||||||
|
@ -265,14 +270,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 20,
|
"execution_count": 9,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Let's make a new SVG that's identical to the first\n",
|
"# Let's make a new SVG that's identical to the first\n",
|
||||||
"wsvg(paths, attributes=attributes, filename='output1.svg')"
|
"wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -300,7 +305,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 21,
|
"execution_count": 10,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -363,7 +368,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 22,
|
"execution_count": 11,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -411,7 +416,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 23,
|
"execution_count": 12,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -466,7 +471,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 24,
|
"execution_count": 13,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -509,7 +514,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 25,
|
"execution_count": 14,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -551,7 +556,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 26,
|
"execution_count": 15,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -606,7 +611,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 27,
|
"execution_count": 16,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -641,7 +646,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 28,
|
"execution_count": 17,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"collapsed": false
|
"collapsed": false
|
||||||
},
|
},
|
||||||
|
@ -734,7 +739,7 @@
|
||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython2",
|
"pygments_lexer": "ipython2",
|
||||||
"version": "2.7.11"
|
"version": "2.7.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|
|
@ -225,6 +225,11 @@ Reading SVGSs
|
||||||
from svgpathtools import svg2paths, wsvg
|
from svgpathtools import svg2paths, wsvg
|
||||||
paths, attributes = svg2paths('test.svg')
|
paths, attributes = svg2paths('test.svg')
|
||||||
|
|
||||||
|
# Update: You can now also extract the svg-attributes by setting
|
||||||
|
# return_svg_attributes=True, or with the convenience function svg2paths2
|
||||||
|
from svgpathtools import svg2paths2
|
||||||
|
paths, attributes, svg_attributes = svg2paths2('test.svg')
|
||||||
|
|
||||||
# Let's print out the first path object and the color it was in the SVG
|
# Let's print out the first path object and the color it was in the SVG
|
||||||
# We'll see it is composed of two CubicBezier objects and, in the SVG file it
|
# We'll see it is composed of two CubicBezier objects and, in the SVG file it
|
||||||
# came from, it was red
|
# came from, it was red
|
||||||
|
@ -254,7 +259,7 @@ viewer.
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
# Let's make a new SVG that's identical to the first
|
# Let's make a new SVG that's identical to the first
|
||||||
wsvg(paths, attributes=attributes, filename='output1.svg')
|
wsvg(paths, attributes=attributes, svg_attributes=svg_attributes, filename='output1.svg')
|
||||||
|
|
||||||
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output1.svg
|
.. figure:: https://cdn.rawgit.com/mathandy/svgpathtools/master/output1.svg
|
||||||
:alt: output1.svg
|
:alt: output1.svg
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<svg baseProfile="full" height="600px" version="1.1" viewBox="-20.6525 -20.6525 366.305 366.305" width="600px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg baseProfile="full" height="100%" version="1.1" viewBox="-20.6525 -20.6525 366.305 366.305" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<defs/>
|
<defs/>
|
||||||
<path d="M 10.5,80.0 C 40.0,10.0 65.0,10.0 95.0,80.0 C 125.0,150.0 150.0,150.0 180.0,80.0" fill="none" stroke="red"/>
|
<path d="M 10.5,80.0 C 40.0,10.0 65.0,10.0 95.0,80.0 C 125.0,150.0 150.0,150.0 180.0,80.0" fill="none" stroke="red"/>
|
||||||
<path d="M 84.0,92.0 C 94.0,102.0 114.0,102.0 124.0,92.0" fill="none" stroke="purple"/>
|
<path d="M 84.0,92.0 C 94.0,102.0 114.0,102.0 124.0,92.0" fill="none" stroke="purple"/>
|
||||||
|
|
Before Width: | Height: | Size: 776 B After Width: | Height: | Size: 774 B |
2
setup.py
2
setup.py
|
@ -1,6 +1,6 @@
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
|
|
||||||
VERSION = '1.0.1'
|
VERSION = '1.1'
|
||||||
AUTHOR_NAME = 'Andy Port'
|
AUTHOR_NAME = 'Andy Port'
|
||||||
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
|
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,6 @@ from .misctools import hex2rgb, rgb2hex
|
||||||
from .smoothing import smoothed_path, smoothed_joint, is_differentiable, kinks
|
from .smoothing import smoothed_path, smoothed_joint, is_differentiable, kinks
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .svg2paths import svg2paths
|
from .svg2paths import svg2paths, svg2paths2
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
|
@ -88,7 +88,7 @@ def disvg(paths=None, colors=None,
|
||||||
openinbrowser=True, timestamp=False,
|
openinbrowser=True, timestamp=False,
|
||||||
margin_size=0.1, mindim=600, dimensions=None,
|
margin_size=0.1, mindim=600, dimensions=None,
|
||||||
viewbox=None, text=None, text_path=None, font_size=None,
|
viewbox=None, text=None, text_path=None, font_size=None,
|
||||||
attributes=None):
|
attributes=None, svg_attributes=None):
|
||||||
"""Takes in a list of paths and creates an SVG file containing said paths.
|
"""Takes in a list of paths and creates an SVG file containing said paths.
|
||||||
REQUIRED INPUTS:
|
REQUIRED INPUTS:
|
||||||
:param paths - a list of paths
|
:param paths - a list of paths
|
||||||
|
@ -148,8 +148,11 @@ def disvg(paths=None, colors=None,
|
||||||
(min_x, min_y, width, height). This is different from the display
|
(min_x, min_y, width, height). This is different from the display
|
||||||
dimension of the svg, which can be set through mindim or dimensions.
|
dimension of the svg, which can be set through mindim or dimensions.
|
||||||
|
|
||||||
:param attributes - a dictionary of attributes for the input paths.
|
:param attributes - a list of dictionaries of attributes for the input
|
||||||
This will override any other conflicting settings.
|
paths. Note: This will override any other conflicting settings.
|
||||||
|
|
||||||
|
:param svg_attributes - a dictionary of attributes for output svg.
|
||||||
|
Note: This will override any other conflicting settings.
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
-The unit of length here is assumed to be pixels in all variables.
|
-The unit of length here is assumed to be pixels in all variables.
|
||||||
|
@ -272,7 +275,10 @@ def disvg(paths=None, colors=None,
|
||||||
szy = str(mindim) + 'px'
|
szy = str(mindim) + 'px'
|
||||||
|
|
||||||
# Create an SVG file
|
# Create an SVG file
|
||||||
dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox)
|
if svg_attributes:
|
||||||
|
dwg = Drawing(filename=filename, **svg_attributes)
|
||||||
|
else:
|
||||||
|
dwg = Drawing(filename=filename, size=(szx, szy), viewBox=viewbox)
|
||||||
|
|
||||||
# add paths
|
# add paths
|
||||||
if paths:
|
if paths:
|
||||||
|
@ -367,7 +373,7 @@ def wsvg(paths=None, colors=None,
|
||||||
openinbrowser=False, timestamp=False,
|
openinbrowser=False, timestamp=False,
|
||||||
margin_size=0.1, mindim=600, dimensions=None,
|
margin_size=0.1, mindim=600, dimensions=None,
|
||||||
viewbox=None, text=None, text_path=None, font_size=None,
|
viewbox=None, text=None, text_path=None, font_size=None,
|
||||||
attributes=None):
|
attributes=None, svg_attributes=None):
|
||||||
"""Convenience function; identical to disvg() except that
|
"""Convenience function; identical to disvg() except that
|
||||||
openinbrowser=False by default. See disvg() docstring for more info."""
|
openinbrowser=False by default. See disvg() docstring for more info."""
|
||||||
disvg(paths, colors=colors, filename=filename,
|
disvg(paths, colors=colors, filename=filename,
|
||||||
|
@ -375,5 +381,5 @@ def wsvg(paths=None, colors=None,
|
||||||
node_colors=node_colors, node_radii=node_radii,
|
node_colors=node_colors, node_radii=node_radii,
|
||||||
openinbrowser=openinbrowser, timestamp=timestamp,
|
openinbrowser=openinbrowser, timestamp=timestamp,
|
||||||
margin_size=margin_size, mindim=mindim, dimensions=dimensions,
|
margin_size=margin_size, mindim=mindim, dimensions=dimensions,
|
||||||
viewbox=viewbox, text=text, text_path=text_path,
|
viewbox=viewbox, text=text, text_path=text_path, font_size=font_size,
|
||||||
font_size=font_size, attributes=attributes)
|
attributes=attributes, svg_attributes=svg_attributes)
|
||||||
|
|
|
@ -5,6 +5,7 @@ The main tool being the svg2paths() function."""
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
from xml.dom.minidom import parse
|
from xml.dom.minidom import parse
|
||||||
from os import path as os_path, getcwd
|
from os import path as os_path, getcwd
|
||||||
|
from shutil import copyfile
|
||||||
|
|
||||||
# Internal dependencies
|
# Internal dependencies
|
||||||
from .parser import parse_path
|
from .parser import parse_path
|
||||||
|
@ -31,9 +32,10 @@ def polyline2pathd(polyline_d):
|
||||||
|
|
||||||
|
|
||||||
def svg2paths(svg_file_location,
|
def svg2paths(svg_file_location,
|
||||||
convert_lines_to_paths=True,
|
convert_lines_to_paths=True,
|
||||||
convert_polylines_to_paths=True,
|
convert_polylines_to_paths=True,
|
||||||
convert_polygons_to_paths=True):
|
convert_polygons_to_paths=True,
|
||||||
|
return_svg_attributes=False):
|
||||||
"""
|
"""
|
||||||
Converts an SVG file into a list of Path objects and a list of
|
Converts an SVG file into a list of Path objects and a list of
|
||||||
dictionaries containing their attributes. This currently supports
|
dictionaries containing their attributes. This currently supports
|
||||||
|
@ -45,12 +47,20 @@ def svg2paths(svg_file_location,
|
||||||
objects (converted to Paths)
|
objects (converted to Paths)
|
||||||
:param convert_polygons_to_paths: Set to False to disclude SVG-Polygon
|
:param convert_polygons_to_paths: Set to False to disclude SVG-Polygon
|
||||||
objects (converted to Paths)
|
objects (converted to Paths)
|
||||||
:return: list of Path objects
|
:param return_svg_attributes: Set to True and a dictionary of
|
||||||
|
svg-attributes will be extracted and returned
|
||||||
|
:return: list of Path objects, list of path attribute dictionaries, and
|
||||||
|
(optionally) a dictionary of svg-attributes
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if os_path.dirname(svg_file_location) == '':
|
if os_path.dirname(svg_file_location) == '':
|
||||||
svg_file_location = os_path.join(getcwd(), svg_file_location)
|
svg_file_location = os_path.join(getcwd(), svg_file_location)
|
||||||
|
|
||||||
doc = parse(svg_file_location) # parseString also exists
|
# if pathless_svg:
|
||||||
|
# copyfile(svg_file_location, pathless_svg)
|
||||||
|
# doc = parse(pathless_svg)
|
||||||
|
# else:
|
||||||
|
doc = parse(svg_file_location)
|
||||||
|
|
||||||
def dom2dict(element):
|
def dom2dict(element):
|
||||||
"""Converts DOM elements to dictionaries of attributes."""
|
"""Converts DOM elements to dictionaries of attributes."""
|
||||||
|
@ -62,6 +72,9 @@ def svg2paths(svg_file_location,
|
||||||
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
paths = [dom2dict(el) for el in doc.getElementsByTagName('path')]
|
||||||
d_strings = [el['d'] for el in paths]
|
d_strings = [el['d'] for el in paths]
|
||||||
attribute_dictionary_list = paths
|
attribute_dictionary_list = paths
|
||||||
|
# if pathless_svg:
|
||||||
|
# for el in doc.getElementsByTagName('path'):
|
||||||
|
# el.parentNode.removeChild(el)
|
||||||
|
|
||||||
# Use minidom to extract polyline strings from input SVG, convert to
|
# Use minidom to extract polyline strings from input SVG, convert to
|
||||||
# path strings, add to list
|
# path strings, add to list
|
||||||
|
@ -82,6 +95,32 @@ def svg2paths(svg_file_location,
|
||||||
d_strings += [('M' + l['x1'] + ' ' + l['y1'] +
|
d_strings += [('M' + l['x1'] + ' ' + l['y1'] +
|
||||||
'L' + l['x2'] + ' ' + l['y2']) for l in lines]
|
'L' + l['x2'] + ' ' + l['y2']) for l in lines]
|
||||||
attribute_dictionary_list += lines
|
attribute_dictionary_list += lines
|
||||||
doc.unlink()
|
|
||||||
path_list = [parse_path(d) for d in d_strings]
|
# if pathless_svg:
|
||||||
return path_list, attribute_dictionary_list
|
# with open(pathless_svg, "wb") as f:
|
||||||
|
# doc.writexml(f)
|
||||||
|
|
||||||
|
if return_svg_attributes:
|
||||||
|
svg_attributes = dom2dict(doc.getElementsByTagName('svg')[0])
|
||||||
|
doc.unlink()
|
||||||
|
path_list = [parse_path(d) for d in d_strings]
|
||||||
|
return path_list, attribute_dictionary_list, svg_attributes
|
||||||
|
else:
|
||||||
|
doc.unlink()
|
||||||
|
path_list = [parse_path(d) for d in d_strings]
|
||||||
|
return path_list, attribute_dictionary_list
|
||||||
|
|
||||||
|
|
||||||
|
def svg2paths2(svg_file_location,
|
||||||
|
convert_lines_to_paths=True,
|
||||||
|
convert_polylines_to_paths=True,
|
||||||
|
convert_polygons_to_paths=True,
|
||||||
|
return_svg_attributes=True):
|
||||||
|
"""Convenience function; identical to svg2paths() except that
|
||||||
|
return_svg_attributes=True by default. See svg2paths() docstring for more
|
||||||
|
info."""
|
||||||
|
return svg2paths(svg_file_location=svg_file_location,
|
||||||
|
convert_lines_to_paths=convert_lines_to_paths,
|
||||||
|
convert_polylines_to_paths=convert_polylines_to_paths,
|
||||||
|
convert_polygons_to_paths=convert_polygons_to_paths,
|
||||||
|
return_svg_attributes=return_svg_attributes)
|
||||||
|
|
Loading…
Reference in New Issue