img2gcode 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CBH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include requirements.txt
2
+ include README.md
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.1
2
+ Name: img2gcode
3
+ Version: 1.0.0
4
+ Summary: Convert image to gcode for laser printing
5
+ Home-page: https://github.com/0CBH0/img2gcode
6
+ Author: 0CBH0
7
+ Author-email: maodatou88@163.com
8
+ License: MIT
9
+ Platform: UNKNOWN
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 2
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.6
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+
18
+ # img2gcode
19
+
20
+ Convert image to gcode for laser printing.
21
+
22
+ ## Installation
23
+ ~~~
24
+ python3 -m pip install --upgrade img2gcode
25
+ ~~~
26
+
27
+ ## Usage
28
+ ~~~
29
+ # Basic usage
30
+ img2gcode [options] -i <image_file>
31
+
32
+ # For more information
33
+ img2gcode -h
34
+ ~~~
35
+
36
+
@@ -0,0 +1,17 @@
1
+ # img2gcode
2
+
3
+ Convert image to gcode for laser printing.
4
+
5
+ ## Installation
6
+ ~~~
7
+ python3 -m pip install --upgrade img2gcode
8
+ ~~~
9
+
10
+ ## Usage
11
+ ~~~
12
+ # Basic usage
13
+ img2gcode [options] -i <image_file>
14
+
15
+ # For more information
16
+ img2gcode -h
17
+ ~~~
@@ -0,0 +1,3 @@
1
+ from __future__ import absolute_import
2
+
3
+ __version__ = "1.0.0"
@@ -0,0 +1,304 @@
1
+ import os, sys, getopt
2
+ from PIL import Image
3
+ from collections import defaultdict
4
+
5
+ from img2gcode import __version__
6
+
7
+ class ArgumentList:
8
+ def __init__(self):
9
+ self.src = ""
10
+ self.dst = ""
11
+ self.mx = 1
12
+ self.my = 1
13
+ self.sx = 20000
14
+ self.sy = 20000
15
+ self.p = 30
16
+ self.t = 1
17
+ self.pi = 0
18
+ self.po = 0
19
+ self.ps = 0
20
+ self.pe = 1
21
+ self.ll = 10
22
+ self.ind = 4
23
+ self.link = 1
24
+ self.gapx = 0
25
+ self.gapy = 0
26
+ self.fill = 3
27
+ self.flip = 0
28
+ self.zz = 0
29
+
30
+ def path_fix(inp, dir):
31
+ terms = inp.split("\n")
32
+ res_fix = []
33
+ for i in range(len(terms)):
34
+ if i < len(terms) - 1 and terms[i][:3] == "G1 " and terms[i + 1][:3] == "G1 " and len(terms[i].split(" ")) == len(terms[i + 1].split(" ")):
35
+ merge = True
36
+ ts = {}
37
+ for t in terms[i].split(" "):
38
+ ts[t[0]] = t[1:]
39
+ for t in terms[i + 1].split(" "):
40
+ if t[0] not in ts or t[1:] != ts[t[0]]:
41
+ #if t[0] not in ts or (t[1:] != ts[t[0]] and t[0] == dir):
42
+ merge = False
43
+ break
44
+ if merge:
45
+ continue
46
+ res_fix.append(terms[i])
47
+ return "\n".join(res_fix)
48
+
49
+ def handle_line(img, mx, my, sx, sy, p, pi, po, t, ps, pe, ll, ind, link, gapx, gapy, fill, flip, zz):
50
+ pause = f"G4 P0.01\n"
51
+ # print vline
52
+ SX = "Y" if flip else "X"
53
+ SY = "X" if flip else "Y"
54
+ gcs = defaultdict(lambda: defaultdict(list))
55
+ mskx = [[0 for y in range(img.size[1])] for x in range(img.size[0])]
56
+ line = [0 for _ in range(img.size[1])]
57
+ for x in range(img.size[0]):
58
+ pt = x
59
+ for y in range(img.size[1]):
60
+ line[y] = 1 if img.getpixel((x, y)) < 128 else 0
61
+ ps = 0
62
+ for i in range(1, len(line)+1):
63
+ if i == len(line) or line[i] != line[ps]:
64
+ pe = i - 1
65
+ if line[ps] == 1 and pe - ps > ll:
66
+ mskx[x][ps:pe + 1] = [1 for _ in range(pe - ps + 1)]
67
+ if pe - ps - gapy*2 < gapy * 4:
68
+ print("???")
69
+ gtt = [f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps+gapy)*my, 3)} S0\n"]
70
+ gtt.append(f"G1 {SY}{round((pe-ind)*my, 3)} S{p}\n")
71
+ gtt.append(f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe-gapy)*my, 3)} S0\n")
72
+ gtt.append(f"G1 {SY}{round((ps+ind)*my, 3)} S{p}\n")
73
+ gcs[pt][ps] = ["".join([gtt[0], pause, gtt[1], gtt[2]]), "".join([gtt[2], pause, gtt[3], gtt[0]])]
74
+ ps = i
75
+ # fill vline
76
+ for x in range(1, img.size[0]):
77
+ for y in range(img.size[1]):
78
+ line[y] = 1 if mskx[x - 1][y] == 1 and mskx[x][y] == 1 else 0
79
+ for k in range(1, fill):
80
+ pt = x - 1 + k / fill
81
+ ps = 0
82
+ for i in range(1, len(line)+1):
83
+ if i == len(line) or line[i] != line[ps]:
84
+ pe = i - 1
85
+ if line[ps] == 1:
86
+ if pe - ps - gapy*2 < gapy * 4:
87
+ print("???")
88
+ gtt = [f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps+gapy+zz*(k%2)/2)*my, 3)} S0\n"]
89
+ gtt.append(f"G1 {SY}{round((pe-ind)*my, 3)} S{p}\n")
90
+ gtt.append(f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe-gapy-zz*(k%2)/2)*my, 3)} S0\n")
91
+ gtt.append(f"G1 {SY}{round((ps+ind)*my, 3)} S{p}\n")
92
+ gcs[pt][ps] = ["".join([gtt[0], pause, gtt[1], gtt[2]]), "".join([gtt[2], pause, gtt[3], gtt[0]])]
93
+ ps = i
94
+ gc_x = ""
95
+ for ki, vi in sorted(gcs.items(), key=lambda x: x[0]):
96
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0]):
97
+ gc_x += vj[0]
98
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0], reverse=True):
99
+ gc_x += vj[1]
100
+ gc_x = path_fix(gc_x, "X")
101
+ # print hline
102
+ links = defaultdict(list)
103
+ linke = defaultdict(list)
104
+ gcs = defaultdict(lambda: defaultdict(list))
105
+ msky = [[0 for x in range(img.size[0])] for y in range(img.size[1])]
106
+ line = [0 for _ in range(img.size[0])]
107
+ for y in range(img.size[1]):
108
+ pt = y
109
+ for x in range(img.size[0]):
110
+ line[x] = 1 if img.getpixel((x, y)) < 128 else 0
111
+ ps = 0
112
+ for i in range(1, len(line)+1):
113
+ if i == len(line) or line[i] != line[ps]:
114
+ pe = i - 1
115
+ ms = [mskx[k][y] for k in range(ps, pe + 1)]
116
+ if line[ps] == 1 and pe - ps + 1 > ms.count(1):
117
+ links[ps].append(pt)
118
+ linke[pe].append(pt)
119
+ msky[y][ps:pe + 1] = [1 for _ in range(pe - ps + 1)]
120
+ gtt = [f"G1 {SX}{round((ps+gapx)*mx, 3)} {SY}{round(pt*my, 3)} S0\n"]#+1
121
+ gtt.append(f"G1 {SX}{round((pe-ind)*mx, 3)} S{p}\n")
122
+ gtt.append(f"G1 {SX}{round((pe-gapx)*mx, 3)} {SY}{round(pt*my, 3)} S0\n")
123
+ gtt.append(f"G1 {SX}{round((ps+ind)*mx, 3)} S{p}\n")
124
+ gcs[pt][ps] = ["".join([gtt[0], pause, gtt[1], gtt[2]]), "".join([gtt[2], pause, gtt[3], gtt[0]])]
125
+ ps = i
126
+ # fill hline
127
+ for y in range(1, img.size[1]):
128
+ for x in range(img.size[0]):
129
+ line[x] = 1 if msky[y - 1][x] == 1 and msky[y][x] == 1 else 0
130
+ for k in range(1, fill):
131
+ pt = y - 1 + k / fill
132
+ ps = 0
133
+ for i in range(1, len(line)+1):
134
+ if i == len(line) or line[i] != line[ps]:
135
+ pe = i - 1
136
+ if line[ps] == 1:
137
+ gtt = [f"G1 {SX}{round((ps+gapx+zz*(k%2)/2)*mx, 3)} {SY}{round(pt*my, 3)} S0\n"]#+1
138
+ gtt.append(f"G1 {SX}{round((pe-ind)*mx, 3)} S{p}\n")
139
+ gtt.append(f"G1 {SX}{round((pe-gapx-zz*(k%2)/2)*mx, 3)} {SY}{round(pt*my, 3)} S0\n")
140
+ gtt.append(f"G1 {SX}{round((ps+ind)*mx, 3)} S{p}\n")
141
+ gcs[pt][ps] = ["".join([gtt[0], pause, gtt[1], gtt[2]]), "".join([gtt[2], pause, gtt[3], gtt[0]])]
142
+ ps = i
143
+ gc_y = ""
144
+ for ki, vi in sorted(gcs.items(), key=lambda x: x[0]):
145
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0]):
146
+ gc_y += vj[0]
147
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0], reverse=True):
148
+ gc_y += vj[1]
149
+ gc_y = path_fix(gc_y, "Y")
150
+ # fill links
151
+ gcs = defaultdict(lambda: defaultdict(list))
152
+ for hx, hys in sorted(links.items(), key=lambda x: x[0]):
153
+ lines = []
154
+ s = 0
155
+ for i in range(1, len(hys)):
156
+ if hys[i] - hys[i - 1] > 1:
157
+ lines.append([hys[s], hys[i - 1]])
158
+ s = i
159
+ lines.append([hys[s], hys[-1]])
160
+ for ps, pe in lines:
161
+ for k in range(1, fill * 3):
162
+ pt = hx + k / fill
163
+ gtt = ["", ""]
164
+ if img.getpixel((hx, min(pe + 1, img.size[1] - 1))) < 128 and img.getpixel((min(hx + 1, img.size[0]), min(pe + 1, img.size[1] - 1))) >= 128:
165
+ gtt[0] = f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps+gapy)*my, 3)} S0\n" + pause
166
+ gtt[0] += f"G1 {SY}{round((pe+link)*my, 3)} S{p}\n"
167
+ gtt[0] += f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe+link*2)*my, 3)} S0\n"
168
+ if img.getpixel((hx, max(ps - 1, 0))) < 128 and img.getpixel((min(hx + 1, img.size[0] - 1), max(ps - 1, 0))) >= 128:
169
+ gtt[1] = f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe-gapy)*my, 3)} S0\n" + pause
170
+ gtt[1] += f"G1 {SY}{round((ps-link)*my, 3)} S{p}\n"
171
+ gtt[1] += f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps-link*2)*my, 3)} S0\n"
172
+ if gtt != ["", ""]:
173
+ gcs[pt][ps] = gtt
174
+ # fill linke
175
+ for hx, hys in sorted(linke.items(), key=lambda x: x[0]):
176
+ lines = []
177
+ s = 0
178
+ for i in range(1, len(hys)):
179
+ if hys[i] - hys[i - 1] > 1:
180
+ lines.append([hys[s], hys[i - 1]])
181
+ s = i
182
+ lines.append([hys[s], hys[-1]])
183
+ for ps, pe in lines:
184
+ for k in range(1, fill * 2):
185
+ pt = hx - k / fill
186
+ gtt = ["", ""]
187
+ if img.getpixel((hx, min(pe + 1, img.size[1] - 1))) < 128 and img.getpixel((max(hx - 1, 0), min(pe + 1, img.size[1] - 1))) >= 128:
188
+ gtt[0] = f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps+gapy)*my, 3)} S0\n" + pause
189
+ gtt[0] += f"G1 {SY}{round((pe+link)*my, 3)} S{p}\n"
190
+ gtt[0] += f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe+link*2)*my, 3)} S0\n"
191
+ if img.getpixel((hx, max(ps - 1, 0))) < 128 and img.getpixel((max(hx - 1, 0), max(ps - 1, 0))) >= 128:
192
+ gtt[1] = f"G1 {SX}{round(pt*mx, 3)} {SY}{round((pe-gapy)*my, 3)} S0\n" + pause
193
+ gtt[1] += f"G1 {SY}{round((ps-link)*my, 3)} S{p}\n"
194
+ gtt[1] += f"G1 {SX}{round(pt*mx, 3)} {SY}{round((ps-link*2)*my, 3)} S0\n"
195
+ if gtt != ["", ""]:
196
+ gcs[pt][ps] = gtt
197
+ gc_l = ""
198
+ for ki, vi in sorted(gcs.items(), key=lambda x: x[0]):
199
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0]):
200
+ if vj[0] != "":
201
+ gc_l += vj[0]
202
+ for kj, vj in sorted(vi.items(), key=lambda x: x[0], reverse=True):
203
+ if vj[1] != "":
204
+ gc_l += vj[1]
205
+ gc_l = path_fix(gc_l, "X")
206
+ res = "G0\nG17\nG40\nG21\nG54\nG90\nM3\nM8\nM3\nM8\nM9\nG90\n"
207
+ res += f"G0 {SX}0 {SY}0 S0 F0\nG1 {SX}0 {SY}0 S0 F{sx}\n"
208
+ res += "".join([gc_y for _ in range(t)])
209
+ res += f"G0 {SX}0 {SY}0 S0 F0\nG1 {SX}0 {SY}0 S0 F{sy}\n"
210
+ res += "".join([gc_x for _ in range(t)])
211
+ res += f"G0 {SX}0 {SY}0 S0 F0\nG1 {SX}0 {SY}0 S0 F{sy}\n"
212
+ res += "".join([gc_l for _ in range(t)])
213
+ res += f"G0 {SX}0 {SY}0 S0\nM5\nG90\n"
214
+ return res
215
+
216
+ def img2gcode(args):
217
+ img = Image.open(args.src).convert("L")
218
+ res = handle_line(img, args.mx, args.my, args.sx, args.sy, args.p, args.pi, args.po, args.t, args.ps, args.pe, args.ll, args.ind, args.link, args.gapx, args.gapy, args.fill, args.flip, args.zz)
219
+ gc = open(args.dst, "w")
220
+ r = gc.write(res)
221
+ gc.close()
222
+ img.close()
223
+
224
+ def main():
225
+ opts, terms = getopt.getopt(sys.argv[1:], "hi:o:n:k:x:y:c:d:p:t:a:b:s:e:l:g:j:m:fz",
226
+ ["help", "input=", "output=", "indent=", "link=", "step_x=", "step_y=", "speed_x=", "speed_y=", "power=", "times=", "pause_in=", "pause_out=", "start=", "end=", "limit=", "gap_x=", "gap_y=", "fill=", "flip", "zigzag"])
227
+ args = ArgumentList()
228
+ help_flag = False
229
+ help_info = "Usage:\nimg2gcode [options] -i <image>\nArguments:\n"\
230
+ +"--help, -h\t\tShow this help information\n"\
231
+ +"--input, -i\t\tThe path of source image file\n"\
232
+ +"--output, -o\t\tThe path of generated gcode file (default: same as input)\n"\
233
+ +"--indent, -n\t\tThe end indentation of lines (pixel, default: 4)\n"\
234
+ +"--link, -k\t\tThe length of links (pixel, default: 1)\n"\
235
+ +"--step_x, -x\t\tStep on x-axis (step/pixel, default: 1)\n"\
236
+ +"--step_y, -y\t\tStep on y-axis (step/pixel, default: 1)\n"\
237
+ +"--speed_x, -c\t\tSpeed on x-axis (1-20000, default: 20000)\n"\
238
+ +"--speed_y, -d\t\tSpeed on y-axis (1-20000, default: 20000)\n"\
239
+ +"--power, -p\t\tPower of laser (0-1000, default: 30)\n"\
240
+ +"--times, -t\t\tNumber of exposures (default: 1)\n"\
241
+ +"--pause_in, -a\t\tPause time before laser on (sec, default: 0)\n"\
242
+ +"--pause_out, -b\t\tPause time after laser off (sec, default: 0)\n"\
243
+ +"--start, -s\t\tStart y position for test (default: 0)\n"\
244
+ +"--end, -e\t\tEnd y position for test (default: 1)\n"\
245
+ +"--limit, -l\t\tThe min length of line to draw (default: 10)\n"\
246
+ +"--gap_x, -g\t\tThe gap for matching x-axis (pixel, default: 0)\n"\
247
+ +"--gap_y, -j\t\tThe gap for matching y-axis (pixel, default: 0)\n"\
248
+ +"--fill, -m\t\tThe padding times for blocks (default: 3)\n"\
249
+ +"--flip, -f\t\tFlip image\n"\
250
+ +"--zigzag, -z\t\tUsing zigzag padding\n"
251
+ for opt, arg in opts:
252
+ if opt in ("--help", "-h"):
253
+ help_flag = True
254
+ elif opt in ("--input", "-i"):
255
+ args.src = arg
256
+ elif opt in ("--output", "-o"):
257
+ args.dst = arg
258
+ elif opt in ("--indent", "-n"):
259
+ args.ind = max(round(float(arg), 3), 0)
260
+ elif opt in ("--link", "-k"):
261
+ args.link = max(round(float(arg), 3), 0)
262
+ elif opt in ("--step_x", "-x"):
263
+ args.mx = max(float(arg), 0)
264
+ elif opt in ("--step_y", "-y"):
265
+ args.my = max(float(arg), 0)
266
+ elif opt in ("--speed_x", "-c"):
267
+ args.sx = max(int(arg), 1)
268
+ elif opt in ("--speed_y", "-d"):
269
+ args.sy = max(int(arg), 1)
270
+ elif opt in ("--power", "-p"):
271
+ args.p = max(int(arg), 0)
272
+ elif opt in ("--times", "-t"):
273
+ args.t = max(int(arg), 1)
274
+ elif opt in ("--pause_in", "-a"):
275
+ args.pi = max(round(float(arg), 3), 0)
276
+ elif opt in ("--pause_out", "-b"):
277
+ args.po = max(round(float(arg), 3), 0)
278
+ elif opt in ("--start", "-s"):
279
+ args.ps = min(max(round(float(arg), 3), 0), 1)
280
+ elif opt in ("--end", "-e"):
281
+ args.pe = min(max(round(float(arg), 3), 0), 1)
282
+ elif opt in ("--limit", "-l"):
283
+ args.ll = max(0, int(arg))
284
+ elif opt in ("--gap_x", "-g"):
285
+ args.gapx = round(float(arg), 3)
286
+ elif opt in ("--gap_y", "-j"):
287
+ args.gapy = round(float(arg),3)
288
+ elif opt in ("--fill", "-m"):
289
+ args.fill = max(0, int(arg))
290
+ elif opt in ("--flip", "-f"):
291
+ args.flip = 1
292
+ elif opt in ("--zigzag", "-z"):
293
+ args.zz = 1
294
+ args.dst = os.path.splitext(args.src)[0] + ".gcode" if args.dst == "" else args.dst
295
+ print("img2gcode - Version: "+__version__)
296
+ if help_flag or args.src == "":
297
+ print(help_info)
298
+ sys.exit()
299
+ print(f"Converting {args.src} ...")
300
+ img2gcode(args)
301
+ print(f"Done!")
302
+
303
+ if __name__ == "__main__":
304
+ main()
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.1
2
+ Name: img2gcode
3
+ Version: 1.0.0
4
+ Summary: Convert image to gcode for laser printing
5
+ Home-page: https://github.com/0CBH0/img2gcode
6
+ Author: 0CBH0
7
+ Author-email: maodatou88@163.com
8
+ License: MIT
9
+ Platform: UNKNOWN
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 2
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.6
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+
18
+ # img2gcode
19
+
20
+ Convert image to gcode for laser printing.
21
+
22
+ ## Installation
23
+ ~~~
24
+ python3 -m pip install --upgrade img2gcode
25
+ ~~~
26
+
27
+ ## Usage
28
+ ~~~
29
+ # Basic usage
30
+ img2gcode [options] -i <image_file>
31
+
32
+ # For more information
33
+ img2gcode -h
34
+ ~~~
35
+
36
+
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ requirements.txt
5
+ setup.py
6
+ img2gcode/__init__.py
7
+ img2gcode/__main__.py
8
+ img2gcode.egg-info/PKG-INFO
9
+ img2gcode.egg-info/SOURCES.txt
10
+ img2gcode.egg-info/dependency_links.txt
11
+ img2gcode.egg-info/entry_points.txt
12
+ img2gcode.egg-info/requires.txt
13
+ img2gcode.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ img2gcode = img2gcode.__main__:main
@@ -0,0 +1,5 @@
1
+ pysam
2
+ pandas
3
+ numpy
4
+ plotnine
5
+ Pillow
@@ -0,0 +1 @@
1
+ img2gcode
@@ -0,0 +1,4 @@
1
+ setuptools
2
+ Pillow
3
+ collections
4
+ python>=3.6
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,40 @@
1
+ '''Setup script for img2gcode'''
2
+
3
+ from __future__ import absolute_import
4
+
5
+ import os.path
6
+ from setuptools import setup
7
+ from img2gcode import __version__
8
+
9
+ # The directory containing this file
10
+ HERE = os.path.abspath(os.path.dirname(__file__))
11
+
12
+ # The text of the README file
13
+ with open(os.path.join(HERE, 'README.md')) as fid:
14
+ README = fid.read()
15
+
16
+ # This call to setup() does all the work
17
+ setup(
18
+ name='img2gcode',
19
+ version=__version__,
20
+ description='Convert image to gcode for laser printing',
21
+ long_description=README,
22
+ long_description_content_type='text/markdown',
23
+ url='https://github.com/0CBH0/img2gcode',
24
+ author='0CBH0',
25
+ author_email='maodatou88@163.com',
26
+ license='MIT',
27
+ classifiers=[
28
+ 'License :: OSI Approved :: MIT License',
29
+ 'Programming Language :: Python',
30
+ 'Programming Language :: Python :: 2',
31
+ 'Programming Language :: Python :: 3',
32
+ ],
33
+ packages=['img2gcode'],
34
+ include_package_data=True,
35
+ install_requires=[
36
+ 'pysam', 'pandas', 'numpy', 'plotnine', 'Pillow'
37
+ ],
38
+ python_requires='>=3.6',
39
+ entry_points={'console_scripts': ['img2gcode=img2gcode.__main__:main']},
40
+ )