This repository has been archived by the owner on Oct 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 25
/
jpegexport.py
197 lines (156 loc) · 7.57 KB
/
jpegexport.py
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#! /usr/bin/env python
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
# Author: Giacomo Mirabassi <[email protected]>
# Version: 0.2
import sys
import os
import re
from distutils.spawn import find_executable
import subprocess
import math
import inkex
import simpletransform
inkex.localize()
class JPEGExport(inkex.Effect):
def __init__(self):
"""Init the effect library and get options from gui."""
inkex.Effect.__init__(self)
self.OptionParser.add_option("--path", action="store", type="string", dest="path", default="", help="")
self.OptionParser.add_option("--bgcol", action="store", type="string", dest="bgcol", default="#ffffff", help="")
self.OptionParser.add_option("--quality", action="store", type="int", dest="quality", default="90", help="")
self.OptionParser.add_option("--density", action="store", type="int", dest="density", default="90", help="")
self.OptionParser.add_option("--page", action="store", type="inkbool", dest="page", default=False, help="")
self.OptionParser.add_option("--fast", action="store", type="inkbool", dest="fast", default=True, help="")
def effect(self):
"""get selected item coords and call command line command to export as a png"""
# The user must supply a directory to export:
if not self.options.path:
inkex.errormsg(_('Please indicate a file name and path to export the jpg.'))
exit()
if not os.path.basename(self.options.path):
inkex.errormsg(_('Please indicate a file name.'))
exit()
if not os.path.dirname(self.options.path):
inkex.errormsg(_('Please indicate a directory other than your system\'s base directory.'))
exit()
# Test if the directory exists:
if not os.path.exists(os.path.dirname(self.options.path)):
inkex.errormsg(_('The directory "%s" does not exist.') % os.path.dirname(self.options.path))
exit()
outfile=self.options.path
curfile = self.args[-1]
# Test if color is valid
_rgbhexstring = re.compile(r'#[a-fA-F0-9]{6}$')
if not _rgbhexstring.match(self.options.bgcol):
inkex.errormsg(_('Please indicate the background color like this: \"#abc123\" or leave the field empty for white.'))
exit()
bgcol = self.options.bgcol
if self.options.page == False:
if len(self.selected) == 0:
inkex.errormsg(_('Please select something.'))
exit()
coords=self.processSelected()
self.exportArea(int(coords[0]),int(coords[1]),int(coords[2]),int(coords[3]),curfile,outfile,bgcol)
elif self.options.page == True:
self.exportPage(curfile,outfile,bgcol)
def processSelected(self):
"""Iterate trough nodes and find the bounding coordinates of the selected area"""
startx=None
starty=None
endx=None
endy=None
nodelist=[]
root=self.document.getroot();
toty=self.getUnittouu(root.attrib['height'])
scale = self.getUnittouu('1px')
props=['x', 'y', 'width', 'height']
for id in self.selected:
if self.options.fast == True: # uses simpletransform
nodelist.append(self.getElementById(id))
else: # uses command line
rawprops=[]
for prop in props:
command=("inkscape", "--without-gui", "--query-id", id, "--query-"+prop, self.args[-1])
proc=subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
proc.wait()
rawprops.append(math.ceil(self.getUnittouu(proc.stdout.read())))
nodeEndX = rawprops[0] + rawprops[2]
nodeStartY = toty - rawprops[1] - rawprops[3]
nodeEndY = toty - rawprops[1]
if rawprops[0] < startx or startx is None:
startx = rawprops[0]
if nodeStartY < starty or starty is None:
starty = nodeStartY
if nodeEndX > endx or endx is None:
endx = nodeEndX
if nodeEndY > endy or endy is None:
endy = nodeEndY
if self.options.fast == True: # uses simpletransform
bbox = simpletransform.computeBBox(nodelist)
startx = math.ceil(bbox[0])
endx = math.ceil(bbox[1])
h = -bbox[2] + bbox[3]
starty = toty - math.ceil(bbox[2]) -h
endy = toty - math.ceil(bbox[2])
coords = [startx / scale, starty / scale, endx / scale, endy / scale]
return coords
def exportArea(self, x0, y0, x1, y1, curfile, outfile, bgcol):
tmp = self.getTmpPath()
command="inkscape -a %s:%s:%s:%s -d %s -e \"%sjpinkexp.png\" -b \"%s\" %s" % (x0, y0, x1, y1, self.options.density, tmp, bgcol, curfile)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return_code = p.wait()
f = p.stdout
err = p.stderr
self.tojpeg(outfile)
def exportPage(self, curfile, outfile, bgcol):
tmp = self.getTmpPath()
command = "inkscape -C -d %s -e \"%sjpinkexp.png\" -b\"%s\" %s" % (self.options.density, tmp,bgcol, curfile)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return_code = p.wait()
f = p.stdout
err = p.stderr
self.tojpeg(outfile)
def tojpeg(self,outfile):
tmp = self.getTmpPath()
if os.name == 'nt':
outfile = outfile.encode('string-escape')
# set the ImageMagick command to run based on what's installed
if find_executable('magick'):
command = "magick -sampling-factor 4:4:4 -strip -interlace JPEG -colorspace RGB -quality %s -density %s \"%sjpinkexp.png\" \"%s\" " % (self.options.quality, self.options.density, tmp, outfile)
elif find_executable('convert'):
command = "convert \"%sjpinkexp.png\" -sampling-factor 4:4:4 -strip -interlace JPEG -colorspace RGB -quality %s -density %s \"%s\" " % (tmp, self.options.quality, self.options.density, outfile)
else:
inkex.errormsg(_('ImageMagick does not appear to be installed.'))
exit()
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return_code = p.wait()
f = p.stdout
err = p.stderr
def getTmpPath(self):
"""Define the temporary folder path depending on the operating system"""
if os.name == 'nt':
return 'C:\\WINDOWS\\Temp\\'
else:
return '/tmp/'
def getUnittouu(self, param):
try:
return inkex.unittouu(param)
except AttributeError:
return self.unittouu(param)
def _main():
e = JPEGExport()
e.affect()
exit()
if __name__=="__main__":
_main()