Problems with PcbDraw when generating PNG and JPG.

Currently the script uses ImageMagick library. But the SVG conversion
is handled unreliably. ImageMagick has various backends to do it and
some of them don't work. I saw this problem many times, and is now
affecting my system. A more reliable conversion can be achieved using
`rsvg-convert`. Isn't as good as InkScape, but is smaller and works
well.
In the process I'm trimming the extra blank space generated by
PcbDraw when we have objects in layers like "User Drawings" that
extends beyond the PCB size.
I'm also compressing JPGs more aggressively, this makes a real
difference between PNG and JPG outputs. Otherwise the difference
is too small.
This commit is contained in:
Salvador E. Tropea 2020-08-25 13:16:49 -03:00
parent cd8a32f544
commit ee69de6e7d
3 changed files with 55 additions and 16 deletions

View File

@ -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

2
debian/control vendored
View File

@ -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.

View File

@ -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