Projet

Général

Profil

BUILDBOTICS-laser-plugin-for-gimp2.10-AgriLab.py

Nicolas Kaufmann, 03/09/2024 14:59

 
1
#!/usr/bin/env python2
2

    
3
from gimpfu import *
4
import gtk
5

    
6
import math
7
from array import *
8

    
9
gettext.install("gimp20-python", gimp.locale_directory, unicode=True)
10

    
11
def laser_power(min, max, pixel, threshold, intensity):
12
  if 255 - pixel < threshold: return 0
13
  return min + (max - min) * (255 - pixel) * intensity / 25500
14

    
15

    
16
def distance(x1, y1, x2, y2):
17
  return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2))
18
  
19

    
20
def image_to_gcode(timg, drawable, outWidth, pixSize, feedRate,
21
                   minPower, maxPower, minRapid, threshold, intensity) :
22
  
23
  dlg = gtk.FileChooserDialog("Pick a file", None,
24
                              gtk.FILE_CHOOSER_ACTION_SAVE,
25
                              (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
26
  dlg.set_do_overwrite_confirmation(True)
27
  ok = dlg.run()
28
  filename = dlg.get_filename()
29
  dlg.destroy()  
30
  
31
  width = int(outWidth / pixSize)
32
  height = int(timg.height * width / timg.width)
33

    
34
  timg = pdb.gimp_image_duplicate(timg)
35
  pdb.gimp_image_scale(timg, width, height)
36

    
37
  # Flatten image so that we handle alpha channel correctly
38
  pdb.gimp_context_push()
39
  pdb.gimp_context_set_background((255, 255, 255))
40
  pdb.gimp_image_flatten(timg)
41
  pdb.gimp_context_pop()
42

    
43
  pdb.gimp_image_convert_grayscale(timg)
44

    
45
  drawable = pdb.gimp_image_get_active_drawable(timg)
46
  pixels = drawable.get_pixel_rgn(0, 0, width, height)
47
  pixels = array('B', pixels[0:width, 0:height])
48

    
49
  pdb.gimp_progress_init('Generating GCode...', None)
50

    
51
  with open(filename, 'w+') as f:
52
    f.write('G21G90\n T3 M6 G43 H3 M3 $3 S1 M67 E1 Q0 F%d\n' % feedRate)
53

    
54
    forward = True
55
    lastX = lastY = None
56

    
57
    for row in range(height):
58
      y = row
59
      lastPower = None
60

    
61
      pdb.gimp_progress_update(float(row) / height)
62

    
63
      for col in range(width):
64
        x = col if forward else (width - col - 1)
65
        pixel = pixels[width * (height - y - 1) + x]
66
        power = laser_power(minPower, maxPower, pixel, threshold, intensity)
67
        end = col == width - 1
68

    
69
        if col and power != lastPower or end:
70
          rapid = lastPower == 0
71

    
72
          if not end or not rapid:
73
            if rapid and lastX is not None:
74
              dist = distance(x, y, lastX, lastY) * pixSize
75
              if dist < minRapid: rapid = False
76

    
77
            lastX = x
78
            lastY = y
79

    
80
            f.write('G%d X%0.2f Y%0.2f M67 E1 Q%d\n' % (
81
              0 if rapid else 1, x * pixSize, y * pixSize, lastPower))
82

    
83
        lastPower = power
84

    
85
      forward = not forward
86

    
87
    f.write('M5 $3\n')
88

    
89
    pdb.gimp_image_delete(timg)
90
    pdb.gimp_progress_end()
91

    
92

    
93
register(
94
  'BUILDBOTICS-laser-plugin',
95
  N_('Laser engraving by Buildbotics\nCheck us out at buildbotics.com!'),
96
  'Export image to g-code for laser engraving',
97
  'Doug Coffland',
98
  'Doug Coffland',
99
  '2018,2019',
100
  N_('Export g-code for laser engraving...'),
101
  '*',
102
  [
103
    (PF_IMAGE, "timg",       "Input image", None),
104
    (PF_DRAWABLE, "drawable", "Input drawable", None),
105
    (PF_FLOAT,  'outWidth',  'Output image width (mm)', 100),
106
    (PF_FLOAT,  'pixSize',   'Size of one output pixel (mm)', 0.05),
107
    (PF_FLOAT,  'feedRate',  'Feed rate in mm/minute', 3000),
108
    (PF_INT,    'minPower',  'Mimimum LASER S-value', 0),
109
    (PF_INT,    'maxPower',  'Maximum LASER S-value', 100),
110
    (PF_FLOAT,  'minRapid',  'Minimum rapid distance (mm)', 10),
111
    (PF_INT,    'threshold', 'Minimum pixel value', 10),
112
    (PF_SLIDER, 'intensity', 'Laser intensity (%)', 100, [0, 100, 1]),
113
  ],
114
  [],
115
  image_to_gcode,
116
  menu="<Image>/File/Export",
117
  domain=("gimp20-python", gimp.locale_directory)
118
  )
119

    
120
main()
    (1-1/1)