first tests with bitmap plotting, working :)

Sat, 07 Nov 2015 13:30:53 +0100

author
mbayer
date
Sat, 07 Nov 2015 13:30:53 +0100
changeset 1
0c9798d91427
parent 0
ee535cb8fb1a
child 2
660ce16822a9

first tests with bitmap plotting, working :)

.hgignore file | annotate | diff | comparison | revisions
bitmap_plot.py file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Sat Nov 07 13:30:53 2015 +0100
@@ -0,0 +1,4 @@
+syntax: glob
+
+*.pyc
+*.bak
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bitmap_plot.py	Sat Nov 07 13:30:53 2015 +0100
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+ENGRAVE_SPEED = 20 * 60 # mm/min
+TRAVEL_SPEED = 130 * 60
+E_FACTOR = 0.1
+INVERT_PALETTE = True
+
+DPI = 300
+GREY_THRESHOLD = 0
+CHANGE_DIRECTION = True
+
+
+# DO NOT CHANGE WORLD's RULES!
+INCH = 25.4 # mm
+MM_PIXEL = round(INCH / DPI, 4)
+STEPS_PIXEL = MM_PIXEL * 80 # mine is 80 steps/mm on XY
+print "Resolution: %f mm per pixel" % MM_PIXEL
+print "Steps per pixel (needs to be > 5, otherwise marlin joins lines): %f" % STEPS_PIXEL
+
+from PIL import Image
+import sys
+
+def pixel_to_bit(pixel, threshold=128):
+    """Convert the pixel value to a bit."""
+    # some really weird stuff here ;-P
+
+    # RGB to greyscale
+    #print pixel
+    #print type(pixel)
+    if isinstance(pixel, tuple):
+        #rgb
+        pixel = pixel[0]*0.2989 + pixel[1]*0.5870 + pixel[2]*0.1140
+        threshold = 128
+        if pixel > threshold:
+            return 1
+        else:
+            return 0
+
+
+    # color palette
+    if (pixel > 0):
+        return 1
+    else:
+        return 0
+
+#
+# Open the image file and get the basic information about it.
+#
+try:
+    im = Image.open(sys.argv[1])
+except:
+    print "Unable to open %s" % sys.argv[1]
+    exit(-1)
+
+print "format: %s   mode: %s   palette: %s" % (im.format,im.mode,im.palette)
+width,height = im.size
+print "The image is %d x %d" % im.size
+
+pix = im.load()
+
+
+fo = open(sys.argv[1] + ".g", "w")
+#fo.write("G10 P1 X-30.0 Y1.5 Z0.0 R0 S0 ; Laser tool offset\n")
+#fo.write("M218 T1 X.30.0 Y1.5 ; Laser tool offset\")
+#fo.write("G28 X Y ; Home position\n")
+# G90 = absolute positioning, G91 = relative
+#fo.write("M83 ; Set extruder (laser) to relative mode\n")
+fo.write("""
+; Filename: %s
+; GCode generated by bitplotter one-night-quick-hack script (marlin code flavour)
+
+G21 ; Metric
+; We assume Z is in focus height and laser head is focus at bottom left of image!
+G92 X0 Y0 E0; set zero position - new origin
+G90 ; absolute positioning
+M82 ; Set extruder (laser) to absolute positioning
+M201 X1000 Y1000 E500 ; Set acceleration
+M203 X1000 Y1000 Z4 E10 ; Set max feedrate
+M209 S0 ; disable firmware retraction, we dont want to burn holes...
+M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod
+M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement!
+G0 X0 Y0 F%d ; Set moving speed TRAVEL_SPEED
+G1 X0 Y0 F%d ; Set linear engraving speed ENGRAVE_SPEED
+
+""" % (sys.argv[1], TRAVEL_SPEED, ENGRAVE_SPEED) )
+
+fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm" % (
+    im.size[0], im.size[1], DPI, im.size[0]*MM_PIXEL, im.size[1]*MM_PIXEL) )
+
+INVERT_Y = MM_PIXEL * (im.size[1] -1) * (-1)
+
+DIR = 1
+for X in range(im.size[0]):
+    fo.write("; X=%d printing row: direction %i\n" % (X, DIR))
+    fo.write("G92 E0\n")
+    E = 0
+    last_bit = 1 # we engrave on black pixel = 0
+    START_Y = 0
+    if DIR > 0:
+        range_start = 0
+        range_stop = im.size[1]
+    else:
+        range_start = im.size[1] -1
+        range_stop = -1
+
+    for Y in range(range_start, range_stop, DIR):
+        YMM = abs((Y * MM_PIXEL) + INVERT_Y)
+        XMM = X * MM_PIXEL
+        #print "X %d Y %d" % (X, Y)
+        bit = pixel_to_bit(pix[X, Y], GREY_THRESHOLD)
+        if last_bit == bit:
+            if bit == 1:
+                # nothing to do,
+                continue
+            else:
+                # are we at the end of Y range?
+                #print Y
+                if (Y == (im.size[1] - 1)) or (Y == 0):
+                    # draw line
+                    if DIR > 0:
+                        E = E + MM_PIXEL * (Y - START_Y)
+                    else:
+                        E = E + MM_PIXEL * (START_Y - Y)
+                    fo.write("G1 X%.4f Y%.4f E%.4f F%d\n" % (XMM, YMM, E * E_FACTOR, ENGRAVE_SPEED))
+        else:
+            # bit value has changed!
+            if bit == 0:
+                # jump to start of line to write
+                START_Y = Y
+                fo.write("G0 X%.4f Y%.4f F%d\n" % (XMM, YMM, TRAVEL_SPEED))
+            else:
+                # end of line to write
+                if DIR > 0:
+                    E = E + MM_PIXEL * (Y - START_Y)
+                else:
+                    E = E + MM_PIXEL * (START_Y - Y)
+                fo.write("G1 X%.4f Y%.4f E%.4f F%d\n" % (XMM, YMM, E * E_FACTOR, ENGRAVE_SPEED))
+        last_bit = bit
+    if CHANGE_DIRECTION:
+        DIR = DIR * (-1) # change y direction on every X
+
+
+fo.write("M571 S0 E0\n")
+fo.write("M501 ; undo all settings made\n")
+#fo.write("G28 X0 Y0 ; Home position\n")
+
+fo.close()
\ No newline at end of file

mercurial