- working on adding DPI setting for PNG export - update

This commit is contained in:
Marius Stanciu
2020-10-07 00:23:36 +03:00
parent 604f4b72d6
commit efdcc6d6ee
2 changed files with 161 additions and 47 deletions

View File

@@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta
================================================= =================================================
7.10.2020
- working on adding DPI setting for PNG export - update
5.10.2020 5.10.2020
- working on adding DPI setting for PNG export in the Film Tool - working on adding DPI setting for PNG export in the Film Tool

View File

@@ -14,6 +14,8 @@ from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \
from copy import deepcopy from copy import deepcopy
import logging import logging
from shapely.geometry import Polygon, MultiPolygon, Point from shapely.geometry import Polygon, MultiPolygon, Point
import shapely.affinity as affinity
from shapely.ops import unary_union
from reportlab.graphics import renderPDF from reportlab.graphics import renderPDF
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
@@ -353,7 +355,7 @@ class Film(AppTool):
if self.ui.film_mirror_axis.get_value() != 'none': if self.ui.film_mirror_axis.get_value() != 'none':
mirror = self.ui.film_mirror_axis.get_value() mirror = self.ui.film_mirror_axis.get_value()
border = float(self.ui.boundary_entry.get_value()) border = self.ui.boundary_entry.get_value()
if border is None: if border is None:
border = 0 border = 0
@@ -443,22 +445,76 @@ class Film(AppTool):
log.debug("FilmTool.export_negative().make_negative_film()") log.debug("FilmTool.export_negative().make_negative_film()")
scale_reference = 'center' scale_reference = 'center'
# Determine bounding area for svg export
bounds = box.bounds()
size = box.size()
default_dpi = 96 default_dpi = 96
new_png_dpi = self.ui.png_dpi_spinner.get_value() new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / default_dpi dpi_rate = new_png_dpi / default_dpi
if dpi_rate != 1: # Determine bounding area for svg export
bounds = box.bounds()
tr_scale_reference = (bounds[0], bounds[1])
if dpi_rate != 1 and ftype == 'png':
scale_factor_x += dpi_rate scale_factor_x += dpi_rate
scale_factor_y += dpi_rate scale_factor_y += dpi_rate
scale_reference = (bounds[0], bounds[1])
if box.kind.lower() == 'geometry':
flat_geo = []
if box.multigeo:
for tool in box.tools:
flat_geo += box.flatten(box.tools[tool]['solid_geometry'])
box_geo = unary_union(flat_geo)
else:
box_geo = unary_union(box.flatten())
else:
box_geo = unary_union(box.flatten())
skew_ref = 'center'
if skew_reference != 'center':
xmin, ymin, xmax, ymax = box_geo.bounds
if skew_reference == 'topleft':
skew_ref = (xmin, ymax)
elif skew_reference == 'bottomleft':
skew_ref = (xmin, ymin)
elif skew_reference == 'topright':
skew_ref = (xmax, ymax)
elif skew_reference == 'bottomright':
skew_ref = (xmax, ymin)
transformed_box_geo = box_geo
if scale_factor_x and not scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, 1.0,
origin=tr_scale_reference)
elif not scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, scale_factor_y,
origin=tr_scale_reference)
elif scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, scale_factor_y,
origin=tr_scale_reference)
if skew_factor_x and not skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, 0.0, origin=skew_ref)
elif not skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, 0.0, skew_factor_y, origin=skew_ref)
elif skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, skew_factor_y, origin=skew_ref)
if mirror:
if mirror == 'x':
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, -1.0)
if mirror == 'y':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, 1.0)
if mirror == 'both':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, -1.0)
bounds = transformed_box_geo.bounds
size = bounds[2] - bounds[0], bounds[3] - bounds[1]
exported_svg = obj.export_svg(scale_stroke_factor=scale_stroke_factor, exported_svg = obj.export_svg(scale_stroke_factor=scale_stroke_factor,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y, scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y,
skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y, skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y,
mirror=mirror, scale_reference=scale_reference mirror=mirror,
scale_reference=scale_reference, skew_reference=skew_reference
) )
uom = obj.units.lower() uom = obj.units.lower()
@@ -529,10 +585,12 @@ class Film(AppTool):
try: try:
doc_final = StringIO(doc_final) doc_final = StringIO(doc_final)
drawing = svg2rlg(doc_final) drawing = svg2rlg(doc_final)
if new_png_dpi == default_dpi: renderPM.drawToFile(drawing, filename, 'PNG')
renderPM.drawToFile(drawing, filename, 'PNG')
else: # if new_png_dpi == default_dpi:
renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi) # renderPM.drawToFile(drawing, filename, 'PNG')
# else:
# renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi)
except Exception as e: except Exception as e:
log.debug("FilmTool.export_negative() --> PNG output --> %s" % str(e)) log.debug("FilmTool.export_negative() --> PNG output --> %s" % str(e))
return 'fail' return 'fail'
@@ -547,8 +605,7 @@ class Film(AppTool):
drawing = svg2rlg(doc_final) drawing = svg2rlg(doc_final)
p_size = self.ui.pagesize_combo.get_value() p_size = self.ui.pagesize_combo.get_value()
if p_size == 'Bounds': if p_size == 'Bounds': renderPDF.drawToFile(drawing, filename)
renderPDF.drawToFile(drawing, filename)
else: else:
if self.ui.orientation_radio.get_value() == 'p': if self.ui.orientation_radio.get_value() == 'p':
page_size = portrait(self.ui.pagesize[p_size]) page_size = portrait(self.ui.pagesize[p_size])
@@ -569,19 +626,17 @@ class Film(AppTool):
self.app.inform.emit('[success] %s: %s' % (_("Film file exported to"), filename)) self.app.inform.emit('[success] %s: %s' % (_("Film file exported to"), filename))
if use_thread is True: if use_thread is True:
proc = self.app.proc_container.new(_("Generating Film ... Please wait.")) def job_thread_film():
with self.app.proc_container.new(_("Working...")):
try:
make_negative_film(scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
except Exception as e:
log.debug("export_negative() process -> %s" % str(e))
return
def job_thread_film(app_obj): self.app.worker_task.emit({'fcn': job_thread_film, 'params': []})
try:
make_negative_film(scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
except Exception:
proc.done()
return
proc.done()
self.app.worker_task.emit({'fcn': job_thread_film, 'params': [self]})
else: else:
make_negative_film() make_negative_film(scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
def export_positive(self, obj_name, box_name, filename, def export_positive(self, obj_name, box_name, filename,
scale_stroke_factor=0.00, scale_stroke_factor=0.00,
@@ -646,22 +701,76 @@ class Film(AppTool):
log.debug("FilmTool.export_positive().make_positive_film()") log.debug("FilmTool.export_positive().make_positive_film()")
scale_reference = 'center' scale_reference = 'center'
# Determine bounding area for svg export
bounds = box.bounds()
size = box.size()
default_dpi = 96 default_dpi = 96
new_png_dpi = self.ui.png_dpi_spinner.get_value() new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / default_dpi dpi_rate = new_png_dpi / default_dpi
if dpi_rate != 1: # Determine bounding area for svg export
bounds = box.bounds()
tr_scale_reference = (bounds[0], bounds[1])
if dpi_rate != 1 and ftype == 'png':
scale_factor_x += dpi_rate scale_factor_x += dpi_rate
scale_factor_y += dpi_rate scale_factor_y += dpi_rate
scale_reference = (bounds[0], bounds[1])
if box.kind.lower() == 'geometry':
flat_geo = []
if box.multigeo:
for tool in box.tools:
flat_geo += box.flatten(box.tools[tool]['solid_geometry'])
box_geo = unary_union(flat_geo)
else:
box_geo = unary_union(box.flatten())
else:
box_geo = unary_union(box.flatten())
skew_ref = 'center'
if skew_reference != 'center':
xmin, ymin, xmax, ymax = box_geo.bounds
if skew_reference == 'topleft':
skew_ref = (xmin, ymax)
elif skew_reference == 'bottomleft':
skew_ref = (xmin, ymin)
elif skew_reference == 'topright':
skew_ref = (xmax, ymax)
elif skew_reference == 'bottomright':
skew_ref = (xmax, ymin)
transformed_box_geo = box_geo
if scale_factor_x and not scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, 1.0,
origin=tr_scale_reference)
elif not scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, scale_factor_y,
origin=tr_scale_reference)
elif scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, scale_factor_y,
origin=tr_scale_reference)
if skew_factor_x and not skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, 0.0, origin=skew_ref)
elif not skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, 0.0, skew_factor_y, origin=skew_ref)
elif skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, skew_factor_y, origin=skew_ref)
if mirror:
if mirror == 'x':
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, -1.0)
if mirror == 'y':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, 1.0)
if mirror == 'both':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, -1.0)
bounds = transformed_box_geo.bounds
size = bounds[2] - bounds[0], bounds[3] - bounds[1]
exported_svg = obj.export_svg(scale_stroke_factor=scale_stroke_factor, exported_svg = obj.export_svg(scale_stroke_factor=scale_stroke_factor,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y, scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y,
skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y, skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y,
mirror=mirror, scale_reference=scale_reference mirror=mirror,
scale_reference=scale_reference, skew_reference=skew_reference
) )
# Change the attributes of the exported SVG # Change the attributes of the exported SVG
@@ -723,10 +832,12 @@ class Film(AppTool):
try: try:
doc_final = StringIO(doc_final) doc_final = StringIO(doc_final)
drawing = svg2rlg(doc_final) drawing = svg2rlg(doc_final)
if new_png_dpi == default_dpi: renderPM.drawToFile(drawing, filename, 'PNG')
renderPM.drawToFile(drawing, filename, 'PNG')
else: # if new_png_dpi == default_dpi:
renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi) # renderPM.drawToFile(drawing, filename, 'PNG')
# else:
# renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi)
except Exception as e: except Exception as e:
log.debug("FilmTool.export_positive() --> PNG output --> %s" % str(e)) log.debug("FilmTool.export_positive() --> PNG output --> %s" % str(e))
return 'fail' return 'fail'
@@ -744,9 +855,9 @@ class Film(AppTool):
renderPDF.drawToFile(drawing, filename) renderPDF.drawToFile(drawing, filename)
else: else:
if orientation == 'p': if orientation == 'p':
page_size = portrait(self.pagesize[p_size]) page_size = portrait(self.ui.pagesize[p_size])
else: else:
page_size = landscape(self.pagesize[p_size]) page_size = landscape(self.ui.pagesize[p_size])
my_canvas = canvas.Canvas(filename, pagesize=page_size) my_canvas = canvas.Canvas(filename, pagesize=page_size)
my_canvas.translate(bounds[0] * unit, bounds[1] * unit) my_canvas.translate(bounds[0] * unit, bounds[1] * unit)
@@ -762,22 +873,21 @@ class Film(AppTool):
self.app.inform.emit('[success] %s: %s' % (_("Film file exported to"), filename)) self.app.inform.emit('[success] %s: %s' % (_("Film file exported to"), filename))
if use_thread is True: if use_thread is True:
proc = self.app.proc_container.new(_("Generating Film ... Please wait."))
def job_thread_film(): def job_thread_film():
try: with self.app.proc_container.new(_("Working...")):
make_positive_film(p_size=p_size, orientation=orientation, color=color, try:
transparency_level=transparency_level, make_positive_film(p_size=p_size, orientation=orientation, color=color,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y) transparency_level=transparency_level,
except Exception: scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
proc.done() except Exception as e:
return log.debug("export_positive() process -> %s" % str(e))
proc.done() return
self.app.worker_task.emit({'fcn': job_thread_film, 'params': []}) self.app.worker_task.emit({'fcn': job_thread_film, 'params': []})
else: else:
make_positive_film(p_size=p_size, orientation=orientation, color=color, make_positive_film(p_size=p_size, orientation=orientation, color=color,
transparency_level=transparency_level) transparency_level=transparency_level,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
def reset_fields(self): def reset_fields(self):
self.ui.tf_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.ui.tf_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))