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")))))))