added option to replace svg by png in export selection as extension
This commit is contained in:
parent
5f6b6eaf80
commit
26e06ecfe0
@ -12,6 +12,8 @@
|
|||||||
<param name="export_svg" type="bool" gui-text="Export as SVG">true</param>
|
<param name="export_svg" type="bool" gui-text="Export as SVG">true</param>
|
||||||
<param name="export_dxf" type="bool" gui-text="Export as DXF R14 file (mm units)">false</param>
|
<param name="export_dxf" type="bool" gui-text="Export as DXF R14 file (mm units)">false</param>
|
||||||
<param name="export_pdf" type="bool" gui-text="Export as PDF 1.5">false</param>
|
<param name="export_pdf" type="bool" gui-text="Export as PDF 1.5">false</param>
|
||||||
|
<param name="export_png" type="bool" gui-text="Export as PNG">false</param>
|
||||||
|
<param name="replace_by_png" type="bool" gui-text="Replace by PNG">false</param>
|
||||||
<param name="newwindow" type="bool" gui-text="Open file in new Inkscape instance">false</param>
|
<param name="newwindow" type="bool" gui-text="Open file in new Inkscape instance">false</param>
|
||||||
<label>Note: If svg/dxf/pdf already existed before, they might get accidently deleted or overwritten. Please take care!</label>
|
<label>Note: If svg/dxf/pdf already existed before, they might get accidently deleted or overwritten. Please take care!</label>
|
||||||
</page>
|
</page>
|
||||||
|
@ -10,9 +10,13 @@ import subprocess
|
|||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
import warnings
|
import warnings
|
||||||
import inkex
|
import inkex
|
||||||
|
from inkex import Rectangle
|
||||||
import inkex.command
|
import inkex.command
|
||||||
from inkex.command import inkscape, inkscape_command
|
from inkex.command import inkscape, inkscape_command
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from PIL import Image
|
||||||
|
import base64
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from scour.scour import scourString
|
from scour.scour import scourString
|
||||||
@ -34,6 +38,8 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
pars.add_argument("--export_svg", type=inkex.Boolean, default=False, help="Create a svg file")
|
pars.add_argument("--export_svg", type=inkex.Boolean, default=False, help="Create a svg file")
|
||||||
pars.add_argument("--export_dxf", type=inkex.Boolean, default=False, help="Create a dxf file")
|
pars.add_argument("--export_dxf", type=inkex.Boolean, default=False, help="Create a dxf file")
|
||||||
pars.add_argument("--export_pdf", type=inkex.Boolean, default=False, help="Create a pdf file")
|
pars.add_argument("--export_pdf", type=inkex.Boolean, default=False, help="Create a pdf file")
|
||||||
|
pars.add_argument("--export_png", type=inkex.Boolean, default=False, help="Create a png file")
|
||||||
|
pars.add_argument("--replace_by_png", type=inkex.Boolean, default=False, help="Replace selection by png export")
|
||||||
pars.add_argument("--newwindow", type=inkex.Boolean, default=False, help="Open file in new Inkscape window")
|
pars.add_argument("--newwindow", type=inkex.Boolean, default=False, help="Open file in new Inkscape window")
|
||||||
|
|
||||||
def openExplorer(self, dir):
|
def openExplorer(self, dir):
|
||||||
@ -56,14 +62,20 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
def effect(self):
|
def effect(self):
|
||||||
|
|
||||||
svg_export = self.options.export_svg
|
svg_export = self.options.export_svg
|
||||||
|
extra_param = "--batch-process"
|
||||||
|
|
||||||
if self.options.export_svg is False and \
|
if self.options.export_svg is False and \
|
||||||
self.options.export_dxf is False and \
|
self.options.export_dxf is False and \
|
||||||
self.options.export_pdf is False and \
|
self.options.export_pdf is False and \
|
||||||
|
self.options.export_png is False and \
|
||||||
|
self.options.replace_by_png is False and \
|
||||||
self.options.newwindow is False:
|
self.options.newwindow is False:
|
||||||
inkex.utils.debug("You must select at least one option to continue!")
|
inkex.utils.debug("You must select at least one option to continue!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.options.replace_by_png is True:
|
||||||
|
self.options.border_offset = 0 #override
|
||||||
|
|
||||||
if not self.svg.selected:
|
if not self.svg.selected:
|
||||||
inkex.errormsg("Selection is empty. Please select some objects first!")
|
inkex.errormsg("Selection is empty. Please select some objects first!")
|
||||||
return
|
return
|
||||||
@ -80,7 +92,11 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
|
|
||||||
bbox = inkex.BoundingBox()
|
bbox = inkex.BoundingBox()
|
||||||
|
|
||||||
for elem in self.svg.selected.values():
|
selected = self.svg.selected
|
||||||
|
firstId = selected[0].get('id')
|
||||||
|
parent = self.svg.getElementById(firstId).getparent()
|
||||||
|
|
||||||
|
for elem in selected.values():
|
||||||
transform = inkex.Transform()
|
transform = inkex.Transform()
|
||||||
parent = elem.getparent()
|
parent = elem.getparent()
|
||||||
if parent is not None and isinstance(parent, inkex.ShapeElement):
|
if parent is not None and isinstance(parent, inkex.ShapeElement):
|
||||||
@ -121,15 +137,32 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
svg_filename = filename_base + '.svg'
|
svg_filename = filename_base + '.svg'
|
||||||
|
|
||||||
template.append(group)
|
template.append(group)
|
||||||
|
svg_out = os.path.join(tempfile.gettempdir(), svg_filename)
|
||||||
|
|
||||||
if not self.options.wrap_transform:
|
if self.options.wrap_transform is False:
|
||||||
self.load(inkscape_command(template.tostring(), select=GROUP_ID, verbs=['SelectionUnGroup']))
|
#self.load(inkscape_command(template.tostring(), select=GROUP_ID, verbs=['SelectionUnGroup;FileSave'])) #fails due to new bug
|
||||||
|
|
||||||
|
#workaround
|
||||||
|
self.save_document(template, svg_out) #export recent file
|
||||||
|
actions_list=[]
|
||||||
|
actions_list.append("SelectionUnGroup")
|
||||||
|
actions_list.append("export-type:svg")
|
||||||
|
actions_list.append("export-filename:{}".format(svg_out))
|
||||||
|
actions_list.append("export-do")
|
||||||
|
extra_param = "--batch-process"
|
||||||
|
actions = ";".join(actions_list)
|
||||||
|
cli_output = inkscape(svg_out, extra_param, actions=actions) #process recent file
|
||||||
|
if len(cli_output) > 0:
|
||||||
|
self.msg("Inkscape returned the following output when trying to run the file export; the file export may still have worked:")
|
||||||
|
self.msg(cli_output)
|
||||||
|
self.load(svg_out) #reload recent file
|
||||||
|
|
||||||
template = self.svg
|
template = self.svg
|
||||||
for child in template.getchildren():
|
for child in template.getchildren():
|
||||||
if child.tag == '{http://www.w3.org/2000/svg}metadata':
|
if child.tag == '{http://www.w3.org/2000/svg}metadata':
|
||||||
template.remove(child)
|
template.remove(child)
|
||||||
|
|
||||||
self.save_document(template, os.path.join(tempfile.gettempdir(), svg_filename)) # save one into temp dir to access for dxf/pdf/new window instance
|
self.save_document(template, svg_out) # save one into temp dir to access for dxf/pdf/new window instance
|
||||||
|
|
||||||
if self.options.export_svg is True:
|
if self.options.export_svg is True:
|
||||||
self.save_document(template, export_dir / svg_filename)
|
self.save_document(template, export_dir / svg_filename)
|
||||||
@ -154,12 +187,49 @@ class ExportObject(inkex.EffectExtension):
|
|||||||
stdout, stderr = proc.communicate()
|
stdout, stderr = proc.communicate()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
inkex.utils.debug("%d %s %s" % (proc.returncode, stdout, stderr))
|
inkex.utils.debug("%d %s %s" % (proc.returncode, stdout, stderr))
|
||||||
|
|
||||||
if self.options.export_pdf is True:
|
if self.options.export_pdf is True:
|
||||||
cli_output = inkscape(os.path.join(tempfile.gettempdir(), svg_filename), actions='export-pdf-version:1.5;export-text-to-path;export-filename:{file_name};export-do;FileClose'.format(file_name=os.path.join(export_dir, filename_base + '.pdf')))
|
cli_output = inkscape(os.path.join(tempfile.gettempdir(), svg_filename), extra_param, actions='export-pdf-version:1.5;export-text-to-path;export-filename:{file_name};export-do'.format(file_name=os.path.join(export_dir, filename_base + '.pdf')))
|
||||||
if len(cli_output) > 0:
|
if len(cli_output) > 0:
|
||||||
self.msg("Inkscape returned the following output when trying to run the file export; the file export may still have worked:")
|
self.msg("Inkscape returned the following output when trying to run the file export; the file export may still have worked:")
|
||||||
self.msg(cli_output)
|
self.msg(cli_output)
|
||||||
|
|
||||||
|
if self.options.export_png is True:
|
||||||
|
cli_output = inkscape(os.path.join(tempfile.gettempdir(), svg_filename), extra_param, actions='export-background:white;export-filename:{file_name};export-do'.format(file_name=os.path.join(export_dir, filename_base + '.png')))
|
||||||
|
if len(cli_output) > 0:
|
||||||
|
self.msg("Inkscape returned the following output when trying to run the file export; the file export may still have worked:")
|
||||||
|
self.msg(cli_output)
|
||||||
|
|
||||||
|
if self.options.replace_by_png is True:
|
||||||
|
#export to png file to temp
|
||||||
|
|
||||||
|
#png_export=os.path.join(export_dir, filename_base + '.png')
|
||||||
|
png_export=os.path.join(tempfile.gettempdir(), filename_base + '.png')
|
||||||
|
cli_output = inkscape(os.path.join(tempfile.gettempdir(), svg_filename), extra_param, actions='export-background:white;export-filename:{};export-do'.format(png_export))
|
||||||
|
if len(cli_output) > 0:
|
||||||
|
self.msg("Inkscape returned the following output when trying to run the file export; the file export may still have worked:")
|
||||||
|
self.msg(cli_output)
|
||||||
|
#then remove the selection and replace it by png
|
||||||
|
#self.msg(parent.get('id'))
|
||||||
|
for elem in selected.values():
|
||||||
|
elem.delete()
|
||||||
|
#read png file and get base64 string from it
|
||||||
|
img = Image.open(png_export)
|
||||||
|
output_buffer = BytesIO()
|
||||||
|
img.save(output_buffer, format='PNG')
|
||||||
|
byte_data = output_buffer.getvalue()
|
||||||
|
base64_str = base64.b64encode(byte_data).decode('UTF-8')
|
||||||
|
|
||||||
|
#finally replace the svg:path(s) with svg:image
|
||||||
|
imgReplacement = etree.SubElement(Rectangle(), '{http://www.w3.org/2000/svg}image')
|
||||||
|
imgReplacement.attrib['x'] = str(bbox.left)
|
||||||
|
imgReplacement.attrib['y'] = str(bbox.top)
|
||||||
|
imgReplacement.attrib['width'] = str(bbox.width)
|
||||||
|
imgReplacement.attrib['height'] = str(bbox.height)
|
||||||
|
imgReplacement.attrib['id'] = firstId
|
||||||
|
imgReplacement.attrib['{http://www.w3.org/1999/xlink}href'] = "data:image/png;base64,{}".format(base64_str)
|
||||||
|
parent.append(imgReplacement)
|
||||||
|
|
||||||
|
|
||||||
def create_document(self):
|
def create_document(self):
|
||||||
document = self.svg.copy()
|
document = self.svg.copy()
|
||||||
|
Reference in New Issue
Block a user