diff --git a/lib/extensions/png_realistic.py b/lib/extensions/png_realistic.py index 24ebce552..e3216efd9 100644 --- a/lib/extensions/png_realistic.py +++ b/lib/extensions/png_realistic.py @@ -13,6 +13,12 @@ from .png_simple import write_png_output class PngRealistic(InkstitchExtension): + def __init__(self, *args, **kwargs): + InkstitchExtension.__init__(self) + + self.arg_parser.add_argument('--notebook') + self.arg_parser.add_argument('--dpi', type=int, default=300, dest='dpi') + def effect(self): if not self.get_elements(): return @@ -26,7 +32,7 @@ class PngRealistic(InkstitchExtension): layer = render_stitch_plan(self.svg, stitch_plan, True, visual_commands=False, render_jumps=False) - write_png_output(self.svg, layer) + write_png_output(self.svg, layer, self.options.dpi) # don't let inkex output the SVG! sys.exit(0) diff --git a/lib/extensions/png_simple.py b/lib/extensions/png_simple.py index 7902b43b2..dd7748d96 100644 --- a/lib/extensions/png_simple.py +++ b/lib/extensions/png_simple.py @@ -20,8 +20,9 @@ class PngSimple(InkstitchExtension): def __init__(self, *args, **kwargs): InkstitchExtension.__init__(self) - self.arg_parser.add_argument('--notebook', type=str, default='') - self.arg_parser.add_argument('--line_width', type=str, default='', dest='line_width') + self.arg_parser.add_argument('--notebook') + self.arg_parser.add_argument('--line_width', type=float, default=0.3, dest='line_width') + self.arg_parser.add_argument('--dpi', type=int, default=300, dest='dpi') def effect(self): if not self.get_elements(): @@ -38,13 +39,13 @@ class PngSimple(InkstitchExtension): layer = render_stitch_plan(self.svg, stitch_plan, False, visual_commands=False, render_jumps=False, line_width=line_width) - write_png_output(self.svg, layer) + write_png_output(self.svg, layer, self.options.dpi) # don't let inkex output the SVG! sys.exit(0) -def write_png_output(svg, layer): +def write_png_output(svg, layer, dpi): with TemporaryDirectory() as tempdir: # Inkex's command functionality also writes files to temp directories like this. temp_svg_path = f"{tempdir}/temp.svg" @@ -52,7 +53,7 @@ def write_png_output(svg, layer): with open(temp_svg_path, "wb") as f: f.write(svg.tostring()) - generate_png(svg, layer, temp_svg_path, temp_png_path) + generate_png(svg, layer, temp_svg_path, temp_png_path, dpi) # inkscape will read the file contents from stdout and copy # to the destination file that the user chose @@ -60,13 +61,13 @@ def write_png_output(svg, layer): sys.stdout.buffer.write(output_file.read()) -def generate_png(svg, layer, input_path, output_path): +def generate_png(svg, layer, input_path, output_path, dpi): inkscape(input_path, actions="; ".join([ - f"export-id:{layer.get_id()}", + f"export-id: {layer.get_id()}", "export-id-only", "export-type:png", - f"export-dpi:{96*8}", - f"export-filename:{output_path}", - f"export-background:{get_pagecolor(svg.namedview)}", + f"export-dpi: {dpi}", + f"export-filename: {output_path}", + f"export-background: {get_pagecolor(svg.namedview)}", "export-do" # Inkscape docs say this should be implicit at the end, but it doesn't seem to be. ])) diff --git a/lib/extensions/stitch_plan_preview.py b/lib/extensions/stitch_plan_preview.py index 464e42008..8f76a4479 100644 --- a/lib/extensions/stitch_plan_preview.py +++ b/lib/extensions/stitch_plan_preview.py @@ -38,7 +38,7 @@ class StitchPlanPreview(InkstitchExtension): self.arg_parser.add_argument("-o", "--overwrite", type=Boolean, default=True, dest="overwrite") def effect(self): - realistic, raster_mult = self.parse_mode() + realistic, dpi = self.parse_mode() # delete old stitch plan self.remove_old() @@ -58,7 +58,7 @@ class StitchPlanPreview(InkstitchExtension): layer = render_stitch_plan(svg, stitch_plan, realistic, visual_commands, render_jumps=self.options.render_jumps) if self.options.ignore_layer and not self.options.mode[-1].isdigit(): add_layer_commands(layer, ["ignore_layer"]) - layer = self.rasterize(svg, layer, raster_mult) + layer = self.rasterize(svg, layer, dpi) # update layer visibility (unchanged, hidden, lower opacity) groups = self.document.getroot().findall(SVG_GROUP_TAG) @@ -72,27 +72,27 @@ class StitchPlanPreview(InkstitchExtension): def parse_mode(self) -> Tuple[bool, Optional[int]]: """ Parse the "mode" option and return a tuple of a bool indicating if realistic rendering should be used, - and an optional int indicating the resolution multiplier to use for rasterization, or None if rasterization should not be used. + and an optional int indicating the dpi value to use for rasterization, or None if rasterization should not be used. """ realistic = False - raster_mult: Optional[int] = None + dpi: Optional[int] = None render_mode = self.options.mode if render_mode == "simple": pass elif render_mode.startswith("realistic-"): realistic = True - raster_option = render_mode.split('-')[1] - if raster_option != "vector": + dpi_option = render_mode.split('-')[1] + if dpi_option != "vector": try: - raster_mult = int(raster_option) + dpi = int(dpi_option) except ValueError: - errormsg(f"Invalid raster mode {raster_option}") + errormsg(f"Invalid raster mode {dpi_option}") sys.exit(1) else: errormsg(f"Invalid render mode {render_mode}") sys.exit(1) - return (realistic, raster_mult) + return (realistic, dpi) def remove_old(self): svg = self.document.getroot() @@ -104,8 +104,8 @@ class StitchPlanPreview(InkstitchExtension): if layer is not None: layer.set('id', svg.get_unique_id('inkstitch_stitch_plan_')) - def rasterize(self, svg: BaseElement, layer: BaseElement, raster_mult: Optional[int]) -> BaseElement: - if raster_mult is None: + def rasterize(self, svg: BaseElement, layer: BaseElement, dpi: Optional[int]) -> BaseElement: + if dpi is None: # Don't rasterize if there's no reason to. return layer else: @@ -121,16 +121,17 @@ class StitchPlanPreview(InkstitchExtension): # Instead, especially because we need to invoke Inkscape anyway to perform the rasterization, we get # the bounding box with query commands before we perform the export. This is quite cheap. out = inkscape(temp_svg_path, actions="; ".join([ - f"select-by-id:{layer.get_id()}", + f"select-by-id: {layer.get_id()}", "query-x", "query-y", "query-width", "query-height", - f"export-id:{layer.get_id()}", + f"export-id: {layer.get_id()}", "export-id-only", - "export-type:png", - f"export-dpi:{96*raster_mult}", - f"export-filename:{temp_png_path}", + "export-type: png", + f"export-dpi: {dpi}", + "export-png-color-mode: RGBA_16", + f"export-filename: {temp_png_path}", "export-do" # Inkscape docs say this should be implicit at the end, but it doesn't seem to be. ])) diff --git a/lib/extensions/zip.py b/lib/extensions/zip.py index 1c33c0805..c2385886d 100644 --- a/lib/extensions/zip.py +++ b/lib/extensions/zip.py @@ -30,7 +30,7 @@ class Zip(InkstitchExtension): def __init__(self, *args, **kwargs): InkstitchExtension.__init__(self) - self.arg_parser.add_argument('--notebook', type=str, default='') + self.arg_parser.add_argument('--notebook') self.arg_parser.add_argument('--custom-file-name', type=str, default='', dest='custom_file_name') # it's kind of obnoxious that I have to do this... @@ -44,10 +44,12 @@ class Zip(InkstitchExtension): self.formats.append('svg') self.arg_parser.add_argument('--format-threadlist', type=Boolean, default=False, dest='threadlist') self.formats.append('threadlist') - self.arg_parser.add_argument('--format-png_realistic', type=Boolean, default=False, dest='png_realistic') + self.arg_parser.add_argument('--format-png-realistic', type=Boolean, default=False, dest='png_realistic') + self.arg_parser.add_argument('--dpi-realistic', type=int, default='', dest='dpi_realistic') self.formats.append('png_realistic') - self.arg_parser.add_argument('--format-png_simple', type=Boolean, default=False, dest='png_simple') - self.arg_parser.add_argument('--png_simple_line_width', type=float, default=0.3, dest='line_width') + self.arg_parser.add_argument('--format-png-simple', type=Boolean, default=False, dest='png_simple') + self.arg_parser.add_argument('--png-simple-line-width', type=float, default=0.3, dest='line_width') + self.arg_parser.add_argument('--dpi-simple', type=int, default='', dest='dpi_simple') self.formats.append('png_simple') self.arg_parser.add_argument('--x-repeats', type=int, default=1, dest='x_repeats', ) @@ -131,21 +133,21 @@ class Zip(InkstitchExtension): elif format == 'png_realistic': output_file = os.path.join(path, f"{base_file_name}_realistic.png") layer = render_stitch_plan(self.svg, stitch_plan, True, visual_commands=False, render_jumps=False) - self.generate_png_output(output_file, layer) + self.generate_png_output(output_file, layer, self.options.dpi_realistic) elif format == 'png_simple': output_file = os.path.join(path, f"{base_file_name}_simple.png") line_width = convert_unit(f"{self.options.line_width}mm", self.svg.document_unit) layer = render_stitch_plan(self.svg, stitch_plan, False, visual_commands=False, render_jumps=False, line_width=line_width) - self.generate_png_output(output_file, layer) + self.generate_png_output(output_file, layer, self.options.dpi_simple) else: write_embroidery_file(output_file, stitch_plan, self.document.getroot()) files.append(output_file) return files - def generate_png_output(self, output_file, layer): + def generate_png_output(self, output_file, layer, dpi): with tempfile.TemporaryDirectory() as tempdir: temp_svg_path = f"{tempdir}/temp.svg" with open(temp_svg_path, "wb") as f: f.write(self.svg.tostring()) - generate_png(self.svg, layer, temp_svg_path, output_file) + generate_png(self.svg, layer, temp_svg_path, output_file, dpi) diff --git a/templates/png_realistic.xml b/templates/png_realistic.xml index 93f0ee2b9..7aae6696b 100644 --- a/templates/png_realistic.xml +++ b/templates/png_realistic.xml @@ -10,6 +10,20 @@ true png_realistic + + + 300 + + + + + + + + + + + diff --git a/templates/png_simple.xml b/templates/png_simple.xml index be12e784f..e42a88190 100644 --- a/templates/png_simple.xml +++ b/templates/png_simple.xml @@ -13,6 +13,7 @@ 0.3 + 300 @@ -20,7 +21,7 @@ - + diff --git a/templates/stitch_plan_preview.xml b/templates/stitch_plan_preview.xml index f71809158..a3385ed3b 100644 --- a/templates/stitch_plan_preview.xml +++ b/templates/stitch_plan_preview.xml @@ -14,8 +14,8 @@ - - + + diff --git a/templates/zip.xml b/templates/zip.xml index c34027eb8..277bbae97 100644 --- a/templates/zip.xml +++ b/templates/zip.xml @@ -9,23 +9,41 @@ Create a ZIP with multiple embroidery file formats using Ink/Stitch true + zip - {%- for format, description, mimetype, category in formats %} - {%- if category != "vector" and category != "debug" %} - false - {%- endif %} - {%- endfor %} - false - false - false - 0.3 - false - zip + + + {%- for format, description, mimetype, category in formats %} + {%- if category != "vector" and category != "debug" %} + false + {%- endif %} + {%- if loop.index == 13 %} + + + + + + {%- endif %} + {%- endfor %} + false + + + + + + false + false + 300 + false + 0.3 + 300 + +