1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 | import base64
import io
import zipfile
import lxml.etree as et
from PIL import Image
from ..render.backends.svg.utils import svg_begin, svg_end
from ..utils.sxml import Xml
from .backends.svg.draw import draw_bitmap
def convert_ora_to_svg(filename):
with zipfile.ZipFile(filename, "r") as archive:
with archive.open("mimetype") as f:
mimetype = f.read().rstrip()
if mimetype != b"image/openraster":
raise Exception("Invalid mime type, found: {}".format(mimetype))
with archive.open("stack.xml") as f:
root = et.fromstring(f.read())
sources = {}
for element in root.getiterator():
src = element.get("src")
if src is not None and src not in sources:
with archive.open(src) as f:
img = Image.open(f)
box = img.getbbox()
if box is None:
sources[src] = None
continue
img = img.crop(box)
temp = io.BytesIO()
img.save(temp, "png")
mime = "image/png"
data = temp.getvalue()
data = base64.b64encode(data).decode("ascii")
if len(data) > 10_0000_000:
raise Exception(
"Layer in ORA is file too big, consider rescaling image"
)
sources[src] = (
data,
mime,
box[0],
box[1],
box[2] - box[0],
box[3] - box[1],
)
width, height = root.get("w"), root.get("h")
xml = Xml()
svg_begin(xml, width, height, inkscape_namespace=True)
_children_to_svg(root, xml, sources)
svg_end(xml)
return xml.to_string()
def _check_visibility(element):
return element.get("visibility") == "visible"
def _stack_to_svg(element, xml, sources):
if not _check_visibility(element):
return
xml.element("g")
x, y = element.get("x"), element.get("y")
if x != "0" or y != "0":
xml.set("transform", "translate({}, {})".format(x, y))
opacity = float(element.get("opacity"))
if opacity < 0.9999:
xml.set("opacity", opacity)
xml.set("inkscape:label", element.get("name"))
_children_to_svg(element, xml, sources)
xml.close("g")
def _layer_to_svg(element, xml, sources):
if not _check_visibility(element):
return
source = sources[element.get("src")]
if source is None:
return
data, mime, x, y, image_width, image_height = source
extra_args = [("inkscape:label", element.get("name"))]
opacity = float(element.get("opacity"))
if opacity is not None and opacity < 0.9999:
extra_args.append(("opacity", opacity))
draw_bitmap(
xml,
float(element.get("x")) + x,
float(element.get("y")) + y,
image_width,
image_height,
mime,
data,
rotation=None,
extra_args=extra_args,
)
def _children_to_svg(element, xml, sources):
for e in reversed(element):
if e.tag == "stack":
_stack_to_svg(e, xml, sources)
elif e.tag == "layer":
_layer_to_svg(e, xml, sources)
|