Mercurial > lasercutter
comparison src/laser/rasterize.clj @ 8:0f48db8d2a05
going to upgrade to clojure 1.2
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 03:21:22 -0400 |
parents | 5e167f275a93 |
children | f952052e37b7 |
comparison
equal
deleted
inserted
replaced
7:5e167f275a93 | 8:0f48db8d2a05 |
---|---|
12 | 12 |
13 (import '(java.io BufferedReader InputStreamReader)) | 13 (import '(java.io BufferedReader InputStreamReader)) |
14 (import '(java.awt.image BufferedImage)) | 14 (import '(java.awt.image BufferedImage)) |
15 | 15 |
16 (use 'clojure.contrib.str-utils) | 16 (use 'clojure.contrib.str-utils) |
17 | 17 (use 'clojure.contrib.seq-utils) |
18 (use 'clojure.contrib.combinatorics) | 18 (use 'clojure.contrib.combinatorics) |
19 | 19 (use 'clojure.contrib.duck-streams) |
20 | 20 |
21 (use 'clojure.contrib.repl-utils) | 21 (use 'clojure.contrib.repl-utils) |
22 | 22 |
23 (set! *print-length* 20) | 23 (set! *print-length* 20) |
24 | 24 |
25 | 25 |
26 (def img "/home/r/graster/test.png") | |
27 | 26 |
28 | 27 |
29 (def feed 120) | 28 (def feed 120) |
30 (def dpi [500, 500]) | 29 (def dpi [500, 500]) |
31 (def on_range [0.0, 0.5]) | 30 |
32 (def overshoot 0.5) | 31 |
33 (def offset [1.0, 1.0]) | |
34 (def tiles [1, 1]) | |
35 (def tile_size [false, false]) | |
36 (def tile_spacing [0.125, 0.125]) | |
37 (def feed 120) | |
38 (def cut_feed 20) | |
39 (def corner_radius 0) | |
40 | 32 |
41 | 33 |
42 (defn preserve-meta [f] | 34 (defn preserve-meta [f] |
43 (fn [& x] (with-meta | 35 (fn [& x] (with-meta |
44 (apply f x) | 36 (apply f x) |
45 (meta (last x))))) | 37 (meta (last x))))) |
46 | 38 |
47 | 39 (defmulti frame-hash-multi class) |
48 | 40 |
49 (defn frame-hash | 41 |
50 "yields a convienent representation for the pixles in an image. | 42 (defmethod frame-hash-multi ImagePlus |
51 Because of the size of the structvre generated, this must only be used | 43 [image+] |
52 in a transient way so that java can do it's garbage collection." | |
53 [#^java.lang.String image-name] | |
54 (let [image+ (ImagePlus. image-name)] | |
55 (with-meta | 44 (with-meta |
56 (let [buf (.. image+ getBufferedImage) | 45 (let [buf (.. image+ getBufferedImage) |
57 color (.getColorModel buf)] | 46 color (.getColorModel buf)] |
58 (apply hash-map | 47 (apply hash-map |
59 (interleave | 48 (interleave |
62 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))] | 51 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))] |
63 (let [data (.getRGB buf x y)] | 52 (let [data (.getRGB buf x y)] |
64 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16) | 53 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16) |
65 :g (bit-shift-right (bit-and 0x00ff00 data) 8) | 54 :g (bit-shift-right (bit-and 0x00ff00 data) 8) |
66 :b (bit-and 0x0000ff data)))))))) | 55 :b (bit-and 0x0000ff data)))))))) |
67 {:width (.getWidth image+) :height (.getHeight image+)}))) | 56 {:width (.getWidth image+) :height (.getHeight image+)})) |
68 | 57 |
69 | 58 |
70 | 59 (defmethod frame-hash-multi String |
71 | 60 [image-name] |
61 (let [image+ (ImagePlus. image-name)] | |
62 (frame-hash-multi image+))) | |
63 | |
64 | |
65 (defn frame-hash | |
66 "yields a convienent representation for the pixles in an image. | |
67 Because of the size of the structvre generated, this must only be used | |
68 in a transient way so that java can do it's garbage collection." | |
69 [something] | |
70 (frame-hash-multi something)) | |
71 | |
72 ;(def frame-hash (preserve-meta frame-hash)) | |
73 | |
72 | 74 |
73 | 75 |
74 | 76 |
75 (def white {:r 255, :g 255, :b 255}) | 77 (def white {:r 255, :g 255, :b 255}) |
76 (def black {:r 0, :g 0, :b 0}) | 78 (def black {:r 0, :g 0, :b 0}) |
99 (defn raster-preamble [] | 101 (defn raster-preamble [] |
100 (str-join \newline | 102 (str-join \newline |
101 ["M63 P0\nG61" | 103 ["M63 P0\nG61" |
102 (str \F feed) | 104 (str \F feed) |
103 "M101" | 105 "M101" |
104 "M3 S1"])) | 106 "M3 S1\n"])) |
105 | 107 |
106 (defn raster-epilogue [] | 108 (defn raster-epilogue [] |
107 (str-join \newline | 109 (str-join \newline |
108 ["M63 PO" | 110 ["M63 P0" |
109 "M5" | 111 "M5" |
110 "M2"])) | 112 "M2\n"])) |
111 | 113 |
112 | 114 |
113 (defn raster-comment [string] | 115 (defn raster-comment [string] |
114 (str "(" (re-gsub #"[()]" "" string) ")")) | 116 (str "(" (re-gsub #"[()]" "" string) ")")) |
115 | 117 |
180 | 182 |
181 | 183 |
182 (defn row->gcode [[x-dpi y-dpi] row] | 184 (defn row->gcode [[x-dpi y-dpi] row] |
183 (let [[x1 y1] (first row) | 185 (let [[x1 y1] (first row) |
184 [x2 y2] (last row)] | 186 [x2 y2] (last row)] |
185 (str (format "GO X%.3f Y%.3f\n" | 187 (str (format "G0 X%.3f Y%.3f\n" |
186 (float (* x1 (/ x-dpi))) | 188 (float (* x1 (/ x-dpi))) |
187 (float (* y1 (/ y-dpi)))) | 189 (float (* y1 (/ y-dpi)))) |
188 | 190 |
189 (format "G1 X%.3f Y%.3f\n" | 191 (format "G1 X%.3f Y%.3f\n" |
190 (float (* x2 (/ x-dpi))) | 192 (float (* x2 (/ x-dpi))) |
243 (sort (fn [[x1 y1][x2 y2]] (> y2 y1)) | 245 (sort (fn [[x1 y1][x2 y2]] (> y2 y1)) |
244 (map first (filter-vals (partial = black) pic)))))) | 246 (map first (filter-vals (partial = black) pic)))))) |
245 | 247 |
246 | 248 |
247 | 249 |
248 | |
249 ;sequence of numbers indicating width | |
250 (def mega | |
251 | |
252 ;sequence of rows | |
253 | |
254 (map (partial sort #(< (first %1) (first %2))) | |
255 (partition-by last | |
256 (sort (fn [[x1 y1][x2 y2]] (> y2 y1)) | |
257 (map first (filter-vals (partial = black) pic)))))) | |
258 | |
259 | |
260 | |
261 | |
262 (defn generate-gmask [pic] | 250 (defn generate-gmask [pic] |
263 | 251 |
264 (str "1 0 0 0\n" | 252 (str "1 0 0 0\n" |
265 (str-join "" (map (fn [[index row]] (row->gmask dpi (even? index) row)) (indexed (make-rows pic)))))) | 253 (str-join "" (map (fn [[index row]] |
254 (row->gmask dpi (odd? index) row)) | |
255 (indexed (make-rows pic)))))) | |
256 | |
257 ;; 1 0 0 0 | |
258 ;; 0 0 1 2.881 | |
259 ;; 0 0 0 2.881 | |
260 ;; 0 1 0 2.863 | |
261 ;; 0 0 0 2.769 | |
262 ;; 0 1 0 2.751 | |
263 ;; 0 0 0 2.729 | |
264 ;; 0 1 0 2.617 | |
265 ;; 0 0 0 2.593 | |
266 ;; 0 1 0 2.561 | |
267 ;; 0 0 0 2.463 | |
268 ;; 0 1 0 2.445 | |
269 ;; 0 0 0 2.385 | |
270 ;; 0 1 0 2.317 | |
271 ;; 0 0 0 2.253 | |
272 ;; 0 1 0 2.233 | |
273 ;; 0 0 0 2.177 | |
274 | |
266 | 275 |
267 | 276 |
268 (defn generate-gcode [pic] | 277 (defn generate-gcode [pic] |
269 (str-join "" (map (partial row->gcode dpi) (make-rows pic)))) | 278 (str (raster-preamble) |
270 | 279 |
271 | 280 |
272 | 281 (str-join "" (map (partial row->gcode dpi) (make-rows pic))) |
282 (raster-epilogue))) | |
283 | |
284 | |
285 | |
286 (defn rotate [degrees #^ImagePlus image] | |
287 (.rotate (.getChannelProcessor image) degrees) | |
288 image) | |
289 | |
290 (defn map-keys [f m] | |
291 (into {} (map (fn [[key val]] [(f key) val]) m))) | |
292 | |
293 | |
294 | |
295 (defn invert-frame-hash [pic] | |
296 (map-keys (fn [[x y]] [x (- (:height (meta pic)) y 1)]) pic )) | |
297 | |
298 | |
299 (defn generate-files [pic] | |
300 (let [image (invert-frame-hash (b&w (frame-hash (rotate 180 (ImagePlus. pic)))))] | |
301 (spit "/home/r/kevin/out.ngc" (generate-gcode image)) | |
302 (spit "/home/r/kevin/out.gmask" (generate-gmask image)) | |
303 image)) | |
304 | |
305 | |
306 | |
307 ;;;; testing | |
308 | |
309 (defn init [] | |
310 (let [stuff | |
311 | |
312 (bound-fn [] | |
313 | |
314 (do | |
315 (println "hi everyone") | |
316 (def img "/home/r/kevin/sing.png") | |
317 (def pic (frame-hash (let [image (ImagePlus. img)] | |
318 (.rotate (.getChannelProcessor image) 180) | |
319 image))) | |
320 | |
321 | |
322 (def test-image | |
323 (invert-frame-hash (b&w (frame-hash (rotate 180 (ImagePlus. img)))))) | |
324 | |
325 (defn test-gmask [] | |
326 (println (str-join "" (take 170 (generate-gmask test-image))))) | |
327 | |
328 (println "ALL variables initialized!") | |
329 | |
330 ))] | |
331 (.start | |
332 (Thread. stuff)))) | |
333 | |
334 | |
335 | |
336 (defn thread-test [] | |
337 | |
338 (let [temp *out*] | |
339 (.start | |
340 (Thread. | |
341 (fn [] | |
342 (with-bindings {#'clojure.core/*out* temp} | |
343 (Thread/sleep 5000) | |
344 (println "hi"))))))) |