Added PNG, EPS and PS outputs to pcb_print.
This commit is contained in:
parent
a2526bf5bd
commit
b7b9b70ac3
|
|
@ -646,7 +646,7 @@ The available values for *type* are:
|
|||
- `svg_sch_print` schematic in SVG format
|
||||
- `pdf_pcb_print` PDF file containing one or more layer and the page frame
|
||||
- `svg_pcb_print` SVG file containing one or more layer and the page frame
|
||||
- `pcb_print` PDF/SVG, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
|
||||
- `pcb_print` PDF/SVG/PNG/EPS/PS, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
|
||||
- `report` generates a report about the PDF. Can include images from the above outputs.
|
||||
- Bill of Materials
|
||||
- `bom` The internal BoM generator.
|
||||
|
|
@ -1522,6 +1522,7 @@ Next time you need this list just use an alias, like this:
|
|||
* PCB Print
|
||||
* Type: `pcb_print`
|
||||
* Description: Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`.
|
||||
Supports PDF, SVG, PNG, EPS and PS formats.
|
||||
KiCad 5: including the frame is slow.
|
||||
KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow.
|
||||
* Valid keys:
|
||||
|
|
@ -1543,7 +1544,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `enable_ki6_frame_fix`: [boolean=false] KiCad 6 doesn't support custom title-block/frames from Python.
|
||||
This option uses KiCad GUI to print the frame, is slow, but works.
|
||||
Always enabled for KiCad 5, which crashes if we try to plot the frame.
|
||||
- `format`: [string='PDF'] [PDF,SVG] Format for the output file/s.
|
||||
- `format`: [string='PDF'] [PDF,SVG,PNG,EPS,PS] Format for the output file/s.
|
||||
Note that for PS you need `ghostscript` which isn't part of the default docker images.
|
||||
- `hide_excluded`: [boolean=false] Hide components in the Fab layer that are marked as excluded by a variant.
|
||||
- `output`: [string='%f-%i%I%v.%x'] Filename for the output (%i=assembly, %x=pdf)/(%i=assembly_page_NN, %x=svg). Affected by global options.
|
||||
- *output_name*: Alias for output.
|
||||
|
|
@ -1573,6 +1575,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `title`: [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||
If it starts with `+` the text is concatenated.
|
||||
- `plot_sheet_reference`: [boolean=true] Include the title-block.
|
||||
- `png_width`: [number=1280] Width of the PNG in pixels.
|
||||
- `title`: [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||
If it starts with `+` the text is concatenated.
|
||||
- `variant`: [string=''] Board variant to apply.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Architecture: all
|
|||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${python3:Depends}, python3-distutils, python3-yaml, kicad (>= 5.1.6), python3-wxgtk4.0
|
||||
Recommends: kibom.inti-cmnb (>= 1.8.0), interactivehtmlbom.inti-cmnb, pcbdraw, imagemagick, librsvg2-bin, python3-xlsxwriter, rar, poppler-utils, python3-lxml
|
||||
Suggests: pandoc, texlive-latex-base, texlive-latex-recommended, git
|
||||
Suggests: pandoc, texlive-latex-base, texlive-latex-recommended, git, ghostscript
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ The available values for *type* are:
|
|||
- `svg_sch_print` schematic in SVG format
|
||||
- `pdf_pcb_print` PDF file containing one or more layer and the page frame
|
||||
- `svg_pcb_print` SVG file containing one or more layer and the page frame
|
||||
- `pcb_print` PDF/SVG, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
|
||||
- `pcb_print` PDF/SVG/PNG/EPS/PS, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
|
||||
- `report` generates a report about the PDF. Can include images from the above outputs.
|
||||
- Bill of Materials
|
||||
- `bom` The internal BoM generator.
|
||||
|
|
|
|||
|
|
@ -952,6 +952,7 @@ outputs:
|
|||
# Don't use the `kicost_variant` when using internal variants/filters
|
||||
variant: ''
|
||||
# PCB Print:
|
||||
# Supports PDF, SVG, PNG, EPS and PS formats.
|
||||
# KiCad 5: including the frame is slow.
|
||||
# KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow.
|
||||
- name: 'pcb_print_example'
|
||||
|
|
@ -972,7 +973,8 @@ outputs:
|
|||
# This option uses KiCad GUI to print the frame, is slow, but works.
|
||||
# Always enabled for KiCad 5, which crashes if we try to plot the frame
|
||||
enable_ki6_frame_fix: false
|
||||
# [string='PDF'] [PDF,SVG] Format for the output file/s
|
||||
# [string='PDF'] [PDF,SVG,PNG,EPS,PS] Format for the output file/s.
|
||||
# Note that for PS you need `ghostscript` which isn't part of the default docker images
|
||||
format: 'PDF'
|
||||
# [boolean=false] Hide components in the Fab layer that are marked as excluded by a variant
|
||||
hide_excluded: false
|
||||
|
|
@ -1025,6 +1027,8 @@ outputs:
|
|||
title: ''
|
||||
# [boolean=true] Include the title-block
|
||||
plot_sheet_reference: true
|
||||
# [number=1280] Width of the PNG in pixels
|
||||
png_width: 1280
|
||||
# [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||
# If it starts with `+` the text is concatenated
|
||||
title: ''
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ from . import log
|
|||
|
||||
logger = log.get_logger()
|
||||
SVG2PDF = 'rsvg-convert'
|
||||
PDF2PS = 'pdf2ps'
|
||||
|
||||
|
||||
# - Implement other rsvg-convert formats
|
||||
# - Use PyPDF2 for pdfunite
|
||||
# - Implement pad, vias, etc colors
|
||||
# - Allow hole color config
|
||||
|
|
@ -47,7 +47,8 @@ def _run_command(cmd):
|
|||
if e.output:
|
||||
logger.debug('Output from command: '+e.output.decode())
|
||||
exit(PDF_PCB_PRINT)
|
||||
logger.debug('Output from command:\n'+cmd_output.decode())
|
||||
if cmd_output.strip():
|
||||
logger.debug('Output from command:\n'+cmd_output.decode())
|
||||
|
||||
|
||||
def hex_to_rgb(value):
|
||||
|
|
@ -94,6 +95,17 @@ def get_width(svg):
|
|||
return float(svg.root.get('viewBox').split(' ')[2])
|
||||
|
||||
|
||||
def to_inches(w):
|
||||
val = float(w[:-2])
|
||||
units = w[-2:]
|
||||
if units == 'cm':
|
||||
return val/2.54
|
||||
if units == 'pt':
|
||||
return val/72.0
|
||||
# Currently impossible for KiCad
|
||||
return val
|
||||
|
||||
|
||||
def merge_svg(input_folder, input_files, output_folder, output_file, black_holes, monochrome):
|
||||
""" Merge all pages into one """
|
||||
first = True
|
||||
|
|
@ -105,6 +117,7 @@ def merge_svg(input_folder, input_files, output_folder, output_file, black_holes
|
|||
svg_out = new_layer
|
||||
# This is the width declared at the beginning of the file
|
||||
base_width = width
|
||||
phys_width = to_inches(new_layer.width)
|
||||
first = False
|
||||
else:
|
||||
root = new_layer.getroot()
|
||||
|
|
@ -117,6 +130,7 @@ def merge_svg(input_folder, input_files, output_folder, output_file, black_holes
|
|||
root.moveto(1, 1)
|
||||
svg_out.append([root])
|
||||
svg_out.save(os.path.join(output_folder, output_file))
|
||||
return phys_width
|
||||
|
||||
|
||||
def create_pdf_from_pages(input_folder, input_files, output_fn):
|
||||
|
|
@ -160,6 +174,23 @@ def svg_to_pdf(input_folder, svg_file, pdf_file):
|
|||
_run_command(cmd)
|
||||
|
||||
|
||||
def svg_to_png(input_folder, svg_file, png_file, width):
|
||||
cmd = [SVG2PDF, '-w', str(width), '-f', 'png', '-o', os.path.join(input_folder, png_file),
|
||||
os.path.join(input_folder, svg_file)]
|
||||
_run_command(cmd)
|
||||
|
||||
|
||||
def svg_to_eps(input_folder, svg_file, eps_file):
|
||||
cmd = [SVG2PDF, '-d', '72', '-p', '72', '-f', 'eps', '-o', os.path.join(input_folder, eps_file),
|
||||
os.path.join(input_folder, svg_file)]
|
||||
_run_command(cmd)
|
||||
|
||||
|
||||
def pdf_to_ps(ps_file, output):
|
||||
cmd = [PDF2PS, ps_file, output]
|
||||
_run_command(cmd)
|
||||
|
||||
|
||||
def create_pdf_from_svg_pages(input_folder, input_files, output_fn):
|
||||
svg_files = []
|
||||
for svg_file in input_files:
|
||||
|
|
@ -267,7 +298,10 @@ class PCB_PrintOptions(VariantOptions):
|
|||
""" Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||
If it starts with `+` the text is concatenated """
|
||||
self.format = 'PDF'
|
||||
""" [PDF,SVG] Format for the output file/s """
|
||||
""" [PDF,SVG,PNG,EPS,PS] Format for the output file/s.
|
||||
Note that for PS you need `ghostscript` which isn't part of the default docker images """
|
||||
self.png_width = 1280
|
||||
""" Width of the PNG in pixels """
|
||||
super().__init__()
|
||||
self._expand_id = 'assembly'
|
||||
|
||||
|
|
@ -319,7 +353,7 @@ class PCB_PrintOptions(VariantOptions):
|
|||
self.restore_fab(GS.board, comps_hash)
|
||||
|
||||
def get_targets(self, out_dir):
|
||||
if self.format == 'SVG':
|
||||
if self.format in ['SVG', 'PNG', 'EPS']:
|
||||
files = []
|
||||
for n in range(len(self.pages)):
|
||||
id = self._expand_id+('_page_%02d' % (n+1))
|
||||
|
|
@ -391,8 +425,11 @@ class PCB_PrintOptions(VariantOptions):
|
|||
patch_svg_file(output, remove_bkg=True)
|
||||
|
||||
def generate_output(self, output):
|
||||
if which(SVG2PDF) is None:
|
||||
logger.error('`{}` not installed and needed for PDF output'.format(SVG2PDF))
|
||||
if self.format != 'SVG' and which(SVG2PDF) is None:
|
||||
logger.error('`{}` not installed. Install `librsvg2-bin` or equivalent'.format(SVG2PDF))
|
||||
exit(MISSING_TOOL)
|
||||
if self.format == 'PS' and which(PDF2PS) is None:
|
||||
logger.error('`{}` not installed. '.format(PDF2PS))
|
||||
logger.error('Install `librsvg2-bin` or equivalent')
|
||||
exit(MISSING_TOOL)
|
||||
output_dir = os.path.dirname(output)
|
||||
|
|
@ -445,19 +482,31 @@ class PCB_PrintOptions(VariantOptions):
|
|||
filelist.append((GS.pcb_basename+"-frame.svg", color))
|
||||
pc.ClosePlot()
|
||||
# 3) Stack all layers in one file
|
||||
if self.format == 'PDF':
|
||||
assembly_file = GS.pcb_basename+"-"+str(n+1)+".svg"
|
||||
else:
|
||||
if self.format == 'SVG':
|
||||
id = self._expand_id+('_page_%02d' % (n+1))
|
||||
assembly_file = self.expand_filename(output_dir, self.output, id, self._expand_ext)
|
||||
else:
|
||||
assembly_file = GS.pcb_basename+"-"+str(n+1)+".svg"
|
||||
logger.debug('- Merging layers to {}'.format(assembly_file))
|
||||
merge_svg(temp_dir, filelist, temp_dir, assembly_file, p.black_holes, p.monochrome)
|
||||
if self.format in ['PNG', 'EPS']:
|
||||
id = self._expand_id+('_page_%02d' % (n+1))
|
||||
out_file = self.expand_filename(output_dir, self.output, id, self._expand_ext)
|
||||
if self.format == 'PNG':
|
||||
svg_to_png(temp_dir, assembly_file, out_file, self.png_width)
|
||||
else:
|
||||
svg_to_eps(temp_dir, assembly_file, out_file)
|
||||
pages.append(assembly_file)
|
||||
self.restore_title()
|
||||
# Join all pages in one file
|
||||
if self.format == 'PDF':
|
||||
if self.format in ['PDF', 'PS']:
|
||||
logger.debug('- Creating output file {}'.format(output))
|
||||
create_pdf_from_svg_pages(temp_dir, pages, output)
|
||||
if self.format == 'PDF':
|
||||
create_pdf_from_svg_pages(temp_dir, pages, output)
|
||||
else:
|
||||
ps_file = os.path.join(temp_dir, GS.pcb_basename+'.ps')
|
||||
create_pdf_from_svg_pages(temp_dir, pages, ps_file)
|
||||
pdf_to_ps(ps_file, output)
|
||||
# Remove the temporal files
|
||||
rmtree(temp_dir)
|
||||
|
||||
|
|
@ -472,6 +521,7 @@ class PCB_PrintOptions(VariantOptions):
|
|||
class PCB_Print(BaseOutput): # noqa: F821
|
||||
""" PCB Print
|
||||
Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`.
|
||||
Supports PDF, SVG, PNG, EPS and PS formats.
|
||||
KiCad 5: including the frame is slow.
|
||||
KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow. """
|
||||
def __init__(self):
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ outputs:
|
|||
# drill_marks: small
|
||||
title: Chau
|
||||
# plot_sheet_reference: false
|
||||
# format: 'SVG'
|
||||
enable_ki6_frame_fix: true
|
||||
format: 'PS'
|
||||
# enable_ki6_frame_fix: true
|
||||
pages:
|
||||
- # monochrome: true
|
||||
scaling: 2.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue