diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ecde9fd..73eb7b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 more than one variant. - Removed warnings about malformed values for DNF components indicating it in its value. +- Problems with PcbDraw when generating PNG and JPG outputs. Now we use a more + reliable conversion methode when available. ## [0.6.1] - 2020-08-20 ### Added diff --git a/debian/control b/debian/control index fd1c75de..8d6edc7e 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,7 @@ Package: kibot Architecture: all Multi-Arch: foreign Depends: ${misc:Depends}, ${python3:Depends}, python3-yaml, kicad (>= 5.1.0), python3-wxgtk4.0 -Recommends: kibom.inti-cmnb (>= 1.8.0), kicad-automation-scripts.inti-cmnb (>= 1.1.2), interactivehtmlbom.inti-cmnb, pcbdraw, python3-xlsxwriter +Recommends: kibom.inti-cmnb (>= 1.8.0), kicad-automation-scripts.inti-cmnb (>= 1.1.2), interactivehtmlbom.inti-cmnb, pcbdraw, imagemagick, librsvg2-bin, python3-xlsxwriter Description: KiCad Bot KiBot is a program which helps you to automate the generation of KiCad output documents easily, repeatable, and most of all, scriptably. diff --git a/kibot/out_pcbdraw.py b/kibot/out_pcbdraw.py index fe45e63d..628304df 100644 --- a/kibot/out_pcbdraw.py +++ b/kibot/out_pcbdraw.py @@ -5,6 +5,7 @@ # Project: KiBot (formerly KiPlot) import os import re +from shutil import which from tempfile import (NamedTemporaryFile) from subprocess import (check_output, STDOUT, CalledProcessError) from .misc import (PCBDRAW, PCBDRAW_ERR) @@ -15,6 +16,8 @@ from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) +SVG2PNG = 'rsvg-convert' +CONVERT = 'convert' class PcbDrawStyle(Optionable): @@ -76,6 +79,29 @@ class PcbDrawRemap(Optionable): pass +def _get_tmp_name(ext): + with NamedTemporaryFile(mode='w', suffix=ext, delete=False) as f: + f.close() + return f.name + + +def _run_command(cmd, tmp_remap=False, tmp_style=False): + logger.debug('Executing: '+str(cmd)) + try: + cmd_output = check_output(cmd, stderr=STDOUT) + except CalledProcessError as e: + logger.error('Failed to run %s, error %d', cmd[0], e.returncode) + if e.output: + logger.debug('Output from command: '+e.output.decode()) + exit(PCBDRAW_ERR) + finally: + if tmp_remap: + os.remove(tmp_remap) + if tmp_style: + os.remove(tmp_style) + logger.debug('Output from command:\n'+cmd_output.decode()) + + class PcbDrawOptions(BaseOptions): def __init__(self): with document: @@ -218,22 +244,33 @@ class PcbDrawOptions(BaseOptions): tmp_remap = None # The board & output cmd.append(GS.pcb_file) - cmd.append(output) + svg = None + if self.format == 'svg': + cmd.append(output) + else: + # PNG and JPG outputs are unreliable + if which(SVG2PNG) is None: + logger.warning('`{}` not installed, using unreliable PNG/JPG conversion'.format(SVG2PNG)) + logger.warning('If you experiment problems install `librsvg2-bin` or equivalent') + cmd.append(output) + elif which(CONVERT) is None: + logger.warning('`{}` not installed, using unreliable PNG/JPG conversion'.format(CONVERT)) + logger.warning('If you experiment problems install `imagemagick` or equivalent') + cmd.append(output) + else: + svg = _get_tmp_name('.svg') + cmd.append(svg) # Execute and inform is successful - logger.debug('Executing: '+str(cmd)) - try: - cmd_output = check_output(cmd, stderr=STDOUT) - except CalledProcessError as e: - logger.error('Failed to run %s, error %d', PCBDRAW, e.returncode) - if e.output: - logger.debug('Output from command: '+e.output.decode()) - exit(PCBDRAW_ERR) - finally: - if tmp_remap: - os.remove(tmp_remap) - if tmp_style: - os.remove(tmp_style) - logger.debug('Output from command:\n'+cmd_output.decode()) + _run_command(cmd, tmp_remap, tmp_style) + if svg is not None: + # Manually convert the SVG to PNG + png = _get_tmp_name('.png') + _run_command([SVG2PNG, '-d', str(self.dpi), '-p', str(self.dpi), svg, '-o', png], svg) + cmd = [CONVERT, '-trim', png] + if self.format == 'jpg': + cmd += ['-quality', '85%'] + cmd.append(output) + _run_command(cmd, png) @output_class