diff --git a/Renderer.py b/Renderer.py new file mode 100644 index 0000000..ffd3678 --- /dev/null +++ b/Renderer.py @@ -0,0 +1,143 @@ +import cairo, os, math + + +class Renderer(): + + def __init__(self, settings): + + self.settings = settings + + self.svg_surface = cairo.SVGSurface("tmp/rendered-output-t.svg", self.settings.bed_actual_x, self.settings.bed_actual_y) + self.svg_context = cairo.Context(self.svg_surface) + self.svg_context.scale(1, 1) + self.svg_context.set_line_width(0.1) + + def clear_screen(self): + + self.svg_context.rectangle(0, 0, self.settings.bed_actual_x, self.settings.bed_actual_y) + self.svg_context.set_source_rgba(1, 1, 1, 1.0) + self.svg_context.fill() + self.svg_context.set_source_rgba(0, 0, 0, 1.0) + self.svg_context.stroke() + + self.svg_context.set_source_rgba(1, 0, 0, 1.0) + self.svg_context.line_to(self.settings.bed_min_x - self.settings.head_x_offset, self.settings.bed_min_y) + self.svg_context.line_to(self.settings.bed_max_x - self.settings.head_x_offset, self.settings.bed_min_y) + self.svg_context.line_to(self.settings.bed_max_x - self.settings.head_x_offset, self.settings.bed_max_y) + self.svg_context.line_to(self.settings.bed_min_x - self.settings.head_x_offset, self.settings.bed_max_y) + self.svg_context.line_to(self.settings.bed_min_x - self.settings.head_x_offset, self.settings.bed_min_y) + self.svg_context.stroke() + self.svg_context.set_source_rgba(0, 0, 0, 1.0) + + # Render GCODE from the gcode-output.gcode output file that was generated in convert_gcode + def render_gcode(self): + + file = open("output/gcode-output.gcode", "r") + + largest_x = 0 + largest_y = 0 + smallest_x = 300 + smallest_y = 300 + x = None + y = None + + for line in file: + + split = line.split(" ") + command = split[0] + operands = split[1:] + + prev_x = x + prev_y = y + + if command == "G1": + for operand in operands: + if operand.startswith("X"): + x = float(operand[1:]) + if x > largest_x: largest_x = x + if x < smallest_x: smallest_x = x + elif operand.startswith("Y"): + y = float(operand[1:]) + if y > largest_y: largest_y = y + if y < smallest_y: smallest_y = y + elif operand.startswith("Z{}".format(self.settings.touch_height + self.settings.raise_height)): + + # signify a lift + if prev_x is not None and prev_y is not None and self.settings.lift_markers: + + self.svg_context.arc(prev_x - self.settings.head_x_offset, prev_y, 0.5, 0, 2 * math.pi) + self.svg_context.stroke() + + self.svg_context.set_source_rgba(1, 1, 1, 1.0) + self.svg_context.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL, + cairo.FONT_WEIGHT_NORMAL) + self.svg_context.set_font_size(3) + self.svg_context.move_to(prev_x - self.settings.head_x_offset, prev_y) + self.svg_context.show_text(str(self.settings.lift_counter)) + self.settings.lift_counter += 1 + self.svg_context.stroke() + self.svg_context.set_source_rgba(0, 0, 0, 1.0) + + prev_x = None + prev_y = None + x = None + y = None + + if (prev_x != x and prev_x is not None) or (prev_y != y and prev_y is not None): + self.svg_context.line_to(prev_x - self.settings.head_x_offset, prev_y) + self.svg_context.line_to(x - self.settings.head_x_offset, y) + self.svg_context.stroke() + + print("Largest X : " + str(largest_x)) + print("Smallest X : " + str(smallest_x)) + + print("Largest Y : " + str(largest_y)) + print("Smallest Y : " + str(smallest_y)) + + if largest_x > self.settings.bed_max_x: + print("X OVERFLOW") + if largest_y > self.settings.bed_max_y: + print("Y OVERFLOW") + + if smallest_x < self.settings.bed_min_x: + print("X_UNDERFLOW") + if smallest_y < self.settings.bed_min_y: + print("Y_UNDERFLOW") + + self.svg_context.set_source_rgba(0, 0, 1, 1.0) + self.svg_context.line_to(smallest_x - self.settings.head_x_offset, smallest_y) + self.svg_context.line_to(largest_x - self.settings.head_x_offset, smallest_y) + self.svg_context.line_to(largest_x - self.settings.head_x_offset, largest_y) + self.svg_context.line_to(smallest_x - self.settings.head_x_offset, largest_y) + self.svg_context.line_to(smallest_x - self.settings.head_x_offset, smallest_y) + self.svg_context.stroke() + self.svg_context.set_source_rgba(0, 0, 0, 1.0) + + self.save_surfaces() + # self.init_surfaces() + + + def save_surfaces(self): + self.svg_surface.write_to_png('tmp/rendered-output.png') + + # Save the SVG so we can view it, then immediately reopen it so it's ready for a re-render + self.svg_surface.finish() + os.rename("tmp/rendered-output-t.svg", "tmp/rendered-output.svg") + self.svg_surface = cairo.SVGSurface("tmp/rendered-output-t.svg", self.settings.bed_actual_x, self.settings.bed_actual_y) + self.svg_context = cairo.Context(self.svg_surface) + + # def render(self): + # self.clear_screen() + # # self.render_gcode() + # # + # # if self.label is not None: + # # self.label.pack_forget() + # # + # # # Apply the rendered gcode image to the UI + # # self.image_ref = ImageTk.PhotoImage( + # # Image.frombuffer("RGBA", (self.bed_actual_x, self.bed_actual_y), self.png_surface.get_data().tobytes(), "raw", "BGRA", 0, 1)) + # # self.label = Label(self, image=self.image_ref) + # # self.label.pack(expand=True, fill="both") + + def toggle_flip_markers(self): + self.settings.lift_markers = not self.settings.lift_markers \ No newline at end of file diff --git a/Svg2GcodeConverter.py b/Svg2GcodeConverter.py new file mode 100644 index 0000000..b560694 --- /dev/null +++ b/Svg2GcodeConverter.py @@ -0,0 +1,147 @@ +from svgpathtools import svg2paths, Line, QuadraticBezier, CubicBezier +import numpy as np +import bezier + + +class Svg2GcodeConverter: + + def __init__(self, settings): + + self.settings = settings + + # First cycle base case flag + self.started = False + + self.gcode_preamble = ''' + G91 ; Set to relative mode for the initial pen lift + G1 Z20 ; Lift head by 20 + G90 ; Set back to absolute position mode + M107 ; Fan off + M190 S0 ; Set bed temp + M104 S0 ; Set nozzle temp + G28 ; home all axes + G0 F{1} ; Set the feed rate + G1 Z{0} ; Move the pen to just above the paper + '''.format(self.settings.touch_height + self.settings.raise_height, self.settings.speed) + + self.gcode_end = ''' + G1 Z{0} F7000 ; Raise the pen high up so we can fit a cap onto it + M104 S0 ; Set the nozzle to 0 + G28 X0 Y0 ; Home back to (0,0) for (x,y) + M84 ; Turn off the motors + '''.format(75) + + # From an input svg file, convert the vector svg paths to gcode tool paths + def convert_gcode(self): + + # read in the svg + paths, attributes = svg2paths("tmp/conversion-output.svg") + + # Find the scale value by resizing based on the svg bounding size + bounding_x_max = None + bounding_x_min = None + bounding_y_max = None + bounding_y_min = None + + for path in paths: + + bbox = path.bbox() + + if bounding_x_max is None: + bounding_x_max = bbox[0] + if bounding_x_min is None: + bounding_x_min = bbox[1] + if bounding_y_max is None: + bounding_y_max = bbox[2] + if bounding_y_min is None: + bounding_y_min = bbox[3] + + bounding_x_min = min(bbox[0], bounding_x_min) + bounding_x_max = max(bbox[1], bounding_x_max) + + bounding_y_min = max(bbox[2], bounding_y_min) + bounding_y_max = max(bbox[3], bounding_y_max) + + print("Maximum X : {:.2f}".format(bounding_x_max)) + print("Minimum Y : {:.2f}".format(bounding_x_min)) + print("Maximum X : {:.2f}".format(bounding_y_max)) + print("Minimum Y : {:.2f}".format(bounding_y_min)) + + max_x_dim = max(bounding_x_max, bounding_x_min) + max_y_dim = max(bounding_y_max, bounding_y_min) + + scale_x = (self.settings.bed_max_x - self.settings.bed_min_x) / max_x_dim + scale_y = (self.settings.bed_max_y - self.settings.bed_min_y) / max_y_dim + + scale = min(scale_x, scale_y) + print("Scaling to : {:.5f}\n".format(scale)) + + # Start the gcode + gcode = "" + gcode += self.gcode_preamble + + # Walk through the paths and create the GCODE + for path in paths: + + previous_x = None + previous_y = None + + for part in path: + + start = part.start + end = part.end + + start_x = start.real * scale + self.settings.offset_x + start_y = start.imag * scale + self.settings.offset_y + + end_x = end.real * scale + self.settings.offset_x + end_y = end.imag * scale + self.settings.offset_y + + # Check to see if the endpoint of the last cycle continues and whether we need to lift the pen or not + lift = True + if previous_x is not None and previous_y is not None: + if abs(start.real - previous_x) < 30 and abs(start.imag - previous_y) < 30: + lift = False + + # if the pen needs to lift, + # if lift: + previous_x = end.real + previous_y = end.imag + + if lift: + gcode += "G1 Z{:.3f}\n".format(self.settings.raise_height + self.settings.touch_height) + else: + gcode += ";# NOT LIFTING [{}]\n".format(self.settings.lift_counter) + + if isinstance(part, CubicBezier): + + nodes = np.asfortranarray([ + [start.real, part.control1.real, part.control2.real, end.real], + [start.imag, part.control1.imag, part.control2.imag, end.imag], + ]) + + curve = bezier.Curve.from_nodes(nodes) + + evals = [] + pos = np.linspace(0.1, 1, 3) + for i in pos: + evals.append(curve.evaluate(i)) + + gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) + gcode += "G1 Z{:.3f} \n".format(self.settings.touch_height) + + for i in evals: + x = i[0][0] + y = i[1][0] + gcode += "G1 X{:.3f} Y{:.3f}\n".format(x * scale + self.settings.offset_x, y * scale + self.settings.offset_y) + + if isinstance(part, Line): + gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) + gcode += "G1 Z{:.3f} \n".format(self.settings.touch_height) + gcode += "G1 X{:.3f} Y{:.3f}\n".format(end_x, end_y) + + gcode += self.gcode_end + + output_gcode = open("output/gcode-output.gcode", "w") + output_gcode.write(gcode) + output_gcode.close() \ No newline at end of file diff --git a/main.py b/main.py index 7153ffc..a6e6d09 100644 --- a/main.py +++ b/main.py @@ -1,330 +1,52 @@ -#from tkinter import Tk, Label, filedialog, Button, LEFT, RIGHT, from tkinter import * from tkinter import filedialog from tkinter.ttk import Notebook from PIL import Image, ImageTk -from svgpathtools import svg2paths, Line, QuadraticBezier, CubicBezier -import cairo, subprocess, bezier, os, math, time -import numpy as np +import subprocess, os, time -class GCodeConverter: +from Renderer import Renderer +from Svg2GcodeConverter import Svg2GcodeConverter - def __init__(self, settings): - self.settings = settings - - # First cycle base case flag - self.started = False - - self.gcode_preamble = ''' - G91 ; Set to relative mode for the initial pen lift - G1 Z20 ; Lift head by 20 - G90 ; Set back to absolute position mode - M107 ; Fan off - M190 S0 ; Set bed temp - M104 S0 ; Set nozzle temp - G28 ; home all axes - G0 F{1} ; Set the feed rate - G1 Z{0} ; Move the pen to just above the paper - '''.format(self.settings.touch_height + self.settings.raise_height, self.settings.speed) - - self.gcode_end = ''' - G1 Z{0} F7000 ; Raise the pen high up so we can fit a cap onto it - M104 S0 ; Set the nozzle to 0 - G28 X0 Y0 ; Home back to (0,0) for (x,y) - M84 ; Turn off the motors - '''.format(75) - - # From an input svg file, convert the vector svg paths to gcode tool paths - def convert_gcode(self): - - # read in the svg - paths, attributes = svg2paths("tmp/conversion-output.svg") - - # Find the scale value by resizing based on the svg bounding size - bounding_x_max = None - bounding_x_min = None - bounding_y_max = None - bounding_y_min = None - - - for path in paths: - - bbox = path.bbox() - - if bounding_x_max is None: - bounding_x_max = bbox[0] - if bounding_x_min is None: - bounding_x_min = bbox[1] - if bounding_y_max is None: - bounding_y_max = bbox[2] - if bounding_y_min is None: - bounding_y_min = bbox[3] - - bounding_x_min = min(bbox[0], bounding_x_min) - bounding_x_max = max(bbox[1], bounding_x_max) - - bounding_y_min = max(bbox[2], bounding_y_min) - bounding_y_max = max(bbox[3], bounding_y_max) - - print("Maximum X : {:.2f}".format(bounding_x_max)) - print("Minimum Y : {:.2f}".format(bounding_x_min)) - print("Maximum X : {:.2f}".format(bounding_y_max)) - print("Minimum Y : {:.2f}".format(bounding_y_min)) - - max_dim = max(bounding_x_max, bounding_x_min, bounding_y_max, bounding_y_min) - scale = (300 - self.settings.offset_x) / max_dim - print("Scaling to : {:.5f}\n".format(scale)) - - # Start the gcode - gcode = "" - gcode += self.gcode_preamble - - # Walk through the paths and create the GCODE - for path in paths: - - previous_x = None - previous_y = None - - for part in path: - - start = part.start - end = part.end - - start_x = start.real * scale + self.settings.offset_x - start_y = start.imag * scale + self.settings.offset_y - - end_x = end.real * scale + self.settings.offset_x - end_y = end.imag * scale + self.settings.offset_y - - # Check to see if the endpoint of the last cycle continues and whether we need to lift the pen or not - lift = True - if previous_x is not None and previous_y is not None: - if abs(start.real - previous_x) < 30 and abs(start.imag - previous_y) < 30: - lift = False - - # if the pen needs to lift, - # if lift: - previous_x = end.real - previous_y = end.imag - - if lift: - gcode += "G1 Z{:.3f}\n".format(self.settings.raise_height + self.settings.touch_height) - else: - gcode += "# NOT LIFTING [{}]\n".format(self.settings.lift_counter) - - if isinstance(part, CubicBezier): - - nodes = np.asfortranarray([ - [start.real, part.control1.real, part.control2.real, end.real], - [start.imag, part.control1.imag, part.control2.imag, end.imag], - ]) - - curve = bezier.Curve.from_nodes(nodes) - - evals = [] - pos = np.linspace(0.1, 1, 10) - for i in pos: - evals.append(curve.evaluate(i)) - - gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) - gcode += "G1 Z{:.3f} \n".format(self.settings.touch_height) - - for i in evals: - x = i[0][0] - y = i[1][0] - gcode += "G1 X{:.3f} Y{:.3f}\n".format(x * scale + self.settings.offset_x, y * scale + self.settings.offset_y) - - if isinstance(part, Line): - gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) - gcode += "G1 Z{:.3f} \n".format(self.settings.touch_height) - gcode += "G1 X{:.3f} Y{:.3f}\n".format(end_x, end_y) - - gcode += self.gcode_end - - output_gcode = open("output/gcode-output.gcode", "w") - output_gcode.write(gcode) - output_gcode.close() - - -class CarioSurfaceSettings: +class Settings: def __init__(self): # Height at which the pen touches and draws on the surface - self.touch_height = 20 + self.touch_height = 12 # How far to raise the pen tip to raise it off the page self.raise_height = 2 # The inherent offset from true 0 we have from the pen bracket self.head_x_offset = 50 # XY movement speed - self.speed = 500 + self.speed = 1000 # Whether we render lift markers self.lift_markers = False # X and Y offsets to place the image on A11 paper - self.offset_x = 75 + self.head_x_offset + self.offset_x = 70 + self.head_x_offset self.offset_y = 20 # Bed dimensions to fit A11 paper - self.bed_max_x = 280 + self.bed_max_x = 300 - 70 + self.head_x_offset + 20 # 20 is to adjust for the misalignment of print bed self.bed_min_x = self.offset_x self.bed_max_y = 280 self.bed_min_y = 20 + self.bed_actual_x = 300 self.bed_actual_y = 300 self.lift_counter = 0 -class CairoSurface(): - - def __init__(self, settings): - - self.settings = settings - - self.png_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.settings.bed_actual_x, self.settings.bed_actual_y) - self.svg_surface = cairo.SVGSurface("tmp/rendered-output-t.svg", self.settings.bed_actual_x, self.settings.bed_actual_y) - - self.png_context = cairo.Context(self.png_surface) - self.png_context.scale(1, 1) - self.png_context.set_line_width(0.4) - - self.svg_context = cairo.Context(self.svg_surface) - self.svg_context.scale(1, 1) - self.svg_context.set_line_width(0.4) - - def clear_screen(self): - - self.png_context.rectangle(0, 0, self.settings.bed_actual_x, self.settings.bed_actual_y) - self.png_context.set_source_rgba(1, 1, 1, 1.0) - self.png_context.fill() - self.png_context.set_source_rgba(0, 0, 0, 1.0) - self.png_context.stroke() - - self.svg_context.rectangle(0, 0, self.settings.bed_actual_x, self.settings.bed_actual_y) - self.svg_context.set_source_rgba(1, 1, 1, 1.0) - self.svg_context.fill() - self.svg_context.set_source_rgba(0, 0, 0, 1.0) - self.svg_context.stroke() - - # Render GCODE from the gcode-output.gcode output file that was generated in convert_gcode - def render_gcode(self): - - file = open("output/gcode-output.gcode", "r") - - largest_x = 0 - largest_y = 0 - smallest_x = 300 - smallest_y = 300 - x = None - y = None - - for line in file: - - split = line.split(" ") - command = split[0] - operands = split[1:] - - prev_x = x - prev_y = y - - if command == "G1": - for operand in operands: - if operand.startswith("X"): - x = float(operand[1:]) - if x > largest_x: largest_x = x - if x < smallest_x: smallest_x = x - elif operand.startswith("Y"): - y = float(operand[1:]) - if y > largest_y: largest_y = y - if y < smallest_y: smallest_y = y - elif operand.startswith("Z{}".format(self.settings.touch_height + self.settings.raise_height)): - - # signify a lift - if prev_x is not None and prev_y is not None and self.settings.lift_markers: - self.png_context.arc(prev_x - self.settings.head_x_offset, prev_y, 0.5, 0, 2 * math.pi) - self.png_context.stroke() - - self.svg_context.arc(prev_x - self.settings.head_x_offset, prev_y, 0.5, 0, 2 * math.pi) - self.svg_context.stroke() - - self.svg_context.set_source_rgba(1, 1, 1, 1.0) - self.svg_context.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL, - cairo.FONT_WEIGHT_NORMAL) - self.svg_context.set_font_size(3) - self.svg_context.move_to(prev_x - self.settings.head_x_offset, prev_y) - self.svg_context.show_text(str(self.settings.lift_counter)) - self.settings.lift_counter += 1 - self.svg_context.stroke() - self.svg_context.set_source_rgba(0, 0, 0, 1.0) - - prev_x = None - prev_y = None - x = None - y = None - - if (prev_x != x and prev_x is not None) or (prev_y != y and prev_y is not None): - self.png_context.line_to(prev_x - self.settings.head_x_offset, prev_y) - self.png_context.line_to(x - self.settings.head_x_offset, y) - self.png_context.stroke() - - self.svg_context.line_to(prev_x - self.settings.head_x_offset, prev_y) - self.svg_context.line_to(x - self.settings.head_x_offset, y) - self.svg_context.stroke() - - print("Largest X : " + str(largest_x)) - print("Smallest X : " + str(smallest_x)) - - print("Largest Y : " + str(largest_y)) - print("Smallest Y : " + str(smallest_y)) - - if largest_x > self.settings.bed_max_x: - print("X OVERFLOW") - if largest_y > self.settings.bed_max_y: - print("Y OVERFLOW") - - if smallest_x < self.settings.bed_min_x: - print("X_UNDERFLOW") - if smallest_y < self.settings.bed_min_y: - print("Y_UNDERFLOW") - - self.save_surfaces() - # self.init_surfaces() - - - def save_surfaces(self): - self.png_surface.write_to_png('tmp/rendered-output.png') - - # Save the SVG so we can view it, then immediately reopen it so it's ready for a re-render - self.svg_surface.finish() - os.rename("tmp/rendered-output-t.svg", "tmp/rendered-output.svg") - self.svg_surface = cairo.SVGSurface("tmp/rendered-output-t.svg", self.settings.bed_actual_x, self.settings.bed_actual_y) - self.svg_context = cairo.Context(self.svg_surface) - - # def render(self): - # self.clear_screen() - # # self.render_gcode() - # # - # # if self.label is not None: - # # self.label.pack_forget() - # # - # # # Apply the rendered gcode image to the UI - # # self.image_ref = ImageTk.PhotoImage( - # # Image.frombuffer("RGBA", (self.bed_actual_x, self.bed_actual_y), self.png_surface.get_data().tobytes(), "raw", "BGRA", 0, 1)) - # # self.label = Label(self, image=self.image_ref) - # # self.label.pack(expand=True, fill="both") - - def toggle_flip_markers(self): - self.settings.lift_markers = not self.settings.lift_markers - -class GCoder(Tk): - +class Tracer(Tk): def update_highpass_value(self, value): self.highpass_filter = value + def update_blur_value(self, value): + self.blur = value def __init__(self): @@ -336,12 +58,15 @@ class GCoder(Tk): if not os.path.exists("tmp"): os.makedirs("tmp") - self.settings = CarioSurfaceSettings() + self.settings = Settings() + + self.filename = None - self.cairo_renderer = CairoSurface(self.settings) - self.gcode_converter = GCodeConverter(self.settings) + self.cairo_renderer = Renderer(self.settings) + self.gcode_converter = Svg2GcodeConverter(self.settings) self.highpass_filter = 0 + self.blur = 0 self.label = None self.pix = None @@ -349,9 +74,9 @@ class GCoder(Tk): self.image_ref = None # Initialize TK - self.geometry("{}x{}".format(self.settings.bed_actual_x, self.settings.bed_actual_y)) + self.geometry("{}x{}".format(500, 500)) - self.n = Notebook(self, width= 200, height =200) + self.n = Notebook(self, width= 400, height =400) self.n.pack(fill=BOTH, expand=1) self.f1 = Frame(self.n) @@ -363,7 +88,7 @@ class GCoder(Tk): self.button = Button(self.rightframe, text="Select Image", command=self.file_select_callback) self.button.pack() - self.button = Button(self.rightframe, text="Re-Render", command=self.cairo_renderer.render_gcode) + self.button = Button(self.rightframe, text="Re-Render", command=self.render) self.button.pack() self.lift_markers_checkbox = Checkbutton(self.rightframe, text="Lift Markers", command=self.cairo_renderer.toggle_flip_markers) @@ -373,6 +98,10 @@ class GCoder(Tk): self.highpass_slider.set(self.highpass_filter) self.highpass_slider.pack() + self.blur_slider = Scale(self.rightframe, command=self.update_blur_value, resolution=0.1, to=5) + self.blur_slider.set(self.blur) + self.blur_slider.pack() + # Start TK self.mainloop() @@ -386,9 +115,12 @@ class GCoder(Tk): self.update_idletasks() - filename = os.path.basename(filepath) + self.filename = os.path.basename(filepath) + + self.render() - self.convert_image(filename) + def render(self): + self.convert_image(self.filename) self.gcode_converter.convert_gcode() self.cairo_renderer.clear_screen() @@ -402,16 +134,16 @@ class GCoder(Tk): if self.label1 is not None: self.label1.pack_forget() - pil_image = Image.frombuffer("RGBA", (self.settings.bed_actual_x, self.settings.bed_actual_y), - self.cairo_renderer.png_surface.get_data().tobytes(), "raw", "BGRA", 0, 1) - scale = self.winfo_width() / pil_image.width - pil_image = pil_image.resize((int(scale * pil_image.width), int(scale * pil_image.height))) + pil_image = Image.open("tmp/rendered-output.png") + + # scale = self.winfo_width() / pil_image.width + # pil_image = pil_image.resize((int(scale * pil_image.width), int(scale * pil_image.height))) self.image_ref = ImageTk.PhotoImage(pil_image) self.label = Label(self.f1, image=self.image_ref) self.n.add(self.f1, text="Converted") self.label.pack(expand=True, fill="both") - self.pic = ImageTk.PhotoImage(file="input-images/{}".format(filename)) + self.pic = ImageTk.PhotoImage(file="input-images/{}".format(self.filename)) self.label1 = Label(self.f2, image=self.pic) self.n.add(self.f2, text="Original") @@ -437,11 +169,16 @@ class GCoder(Tk): print("Running mkbitmap...") start = time.time() - subprocess.call(["mkbitmap", "input-images/{}.bmp".format(base_name), "-x", - # "-f", "{}".format(self.highpass_filter), - # "-b", "0", - "-o", "input-images/{}-n.bmp".format(base_name) - ]) + mkbitmap_args = ["mkbitmap", "input-images/{}.bmp".format(base_name), + "-o", "input-images/{}-n.pbm".format(base_name)] + if self.highpass_filter > 0: + mkbitmap_args.append(["-f", self.highpass_filter]) + + if self.blur > 0: + mkbitmap_args.append(["-b", self.blur]) + + + subprocess.call(mkbitmap_args) print("Run took [{:.2f}] seconds".format(time.time() - start)) print("Running potrace...") @@ -450,7 +187,7 @@ class GCoder(Tk): #"-t", "0.1", "-z", "white", "-b", "svg", - "input-images/{}-n.bmp".format(base_name), + "input-images/{}-n.pbm".format(base_name), "--rotate", "0", "-o", "tmp/conversion-output.svg", ]) @@ -458,5 +195,5 @@ class GCoder(Tk): if __name__ == "__main__": - GCoder() + Tracer()