rlm@0
|
1 (ns laser.rasterize)
|
rlm@0
|
2
|
rlm@0
|
3 (import '(java.io File))
|
rlm@0
|
4 (import '(org.apache.commons.io FileUtils))
|
rlm@0
|
5 (import '(javax.imageio ImageIO) )
|
rlm@0
|
6 (import '(javax.swing JFrame))
|
rlm@0
|
7 (import '(java.awt Color BorderLayout))
|
rlm@0
|
8 (import '(ij ImagePlus IJ))
|
rlm@0
|
9 (import '(java.lang Math))
|
rlm@2
|
10 (import '(java.awt Graphics2D Panel))
|
rlm@0
|
11 (import '(ij Macro))
|
rlm@0
|
12
|
rlm@0
|
13 (import '(java.io BufferedReader InputStreamReader))
|
rlm@0
|
14 (import '(java.awt.image BufferedImage))
|
rlm@0
|
15
|
rlm@0
|
16 (use 'clojure.contrib.str-utils)
|
rlm@0
|
17
|
rlm@0
|
18 (use 'clojure.contrib.combinatorics)
|
rlm@0
|
19
|
rlm@0
|
20
|
rlm@0
|
21 (use 'clojure.contrib.repl-utils)
|
rlm@0
|
22
|
rlm@0
|
23 (set! *print-length* 20)
|
rlm@0
|
24
|
rlm@0
|
25
|
rlm@0
|
26 (def img "/home/r/graster/test.png")
|
rlm@0
|
27
|
rlm@1
|
28
|
rlm@1
|
29 (def feed 120)
|
rlm@1
|
30 (def dpi [500, 500])
|
rlm@1
|
31 (def on_range [0.0, 0.5])
|
rlm@1
|
32 (def overshoot 0.5)
|
rlm@1
|
33 (def offset [1.0, 1.0])
|
rlm@1
|
34 (def tiles [1, 1])
|
rlm@1
|
35 (def tile_size [false, false])
|
rlm@1
|
36 (def tile_spacing [0.125, 0.125])
|
rlm@1
|
37 (def feed 120)
|
rlm@1
|
38 (def cut_feed 20)
|
rlm@1
|
39 (def corner_radius 0)
|
rlm@1
|
40
|
rlm@2
|
41 (defmulti display "Creates a JFrame and displays a buffered image" class)
|
rlm@1
|
42
|
rlm@2
|
43 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil))))
|
rlm@2
|
44
|
rlm@2
|
45 (defmethod display
|
rlm@2
|
46 BufferedImage [image]
|
rlm@2
|
47 (let [panel (makePanel image)
|
rlm@2
|
48 frame (JFrame. "Oh Yeah!")]
|
rlm@2
|
49 (.add frame panel)
|
rlm@2
|
50 (.pack frame)
|
rlm@2
|
51 (.setVisible frame true )
|
rlm@2
|
52 (.setSize frame(.getWidth image) (.getHeight image))))
|
rlm@2
|
53
|
rlm@2
|
54 (defmethod display
|
rlm@2
|
55 ImagePlus [image]
|
rlm@2
|
56 (display (.getBufferedImage image)))
|
rlm@2
|
57
|
rlm@2
|
58 (defmethod display
|
rlm@2
|
59 clojure.lang.PersistentHashMap [frame-hash]
|
rlm@2
|
60 (display (frame-hash->bufferedImage frame-hash)))
|
rlm@2
|
61
|
rlm@2
|
62 (defmethod display
|
rlm@2
|
63 clojure.lang.PersistentArrayMap [frame-hash]
|
rlm@2
|
64 (display (frame-hash->bufferedImage frame-hash)))
|
rlm@1
|
65
|
rlm@1
|
66
|
rlm@0
|
67 (defn frame-hash
|
rlm@0
|
68 "yields a convienent representation for the pixles in an image.
|
rlm@0
|
69 Because of the size of the structvre generated, this must only be used
|
rlm@0
|
70 in a transient way so that java can do it's garbage collection."
|
rlm@0
|
71 [#^java.lang.String image-name]
|
rlm@0
|
72 (let [image+ (ImagePlus. image-name)]
|
rlm@0
|
73 (with-meta
|
rlm@0
|
74 (let [buf (.. image+ getBufferedImage)
|
rlm@0
|
75 color (.getColorModel buf)]
|
rlm@0
|
76 (apply hash-map
|
rlm@0
|
77 (interleave
|
rlm@0
|
78 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]
|
rlm@0
|
79 (vector x y)))
|
rlm@0
|
80 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]
|
rlm@0
|
81 (let [data (.getRGB buf x y)]
|
rlm@0
|
82 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)
|
rlm@0
|
83 :g (bit-shift-right (bit-and 0x00ff00 data) 8)
|
rlm@0
|
84 :b (bit-and 0x0000ff data))))))))
|
rlm@0
|
85 {:width (.getWidth image+) :height (.getHeight image+)})))
|
rlm@0
|
86
|
rlm@0
|
87
|
rlm@1
|
88 (def white {:r 255, :g 255, :b 255})
|
rlm@1
|
89 (def black {:r 0, :g 0, :b 0})
|
rlm@1
|
90
|
rlm@1
|
91 (def expt #(Math/pow %1 %2))
|
rlm@1
|
92
|
rlm@1
|
93 (defn rgb-euclidian
|
rlm@1
|
94 [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]
|
rlm@1
|
95 (expt (+ (expt (- r1 r2) 2)
|
rlm@1
|
96 (expt (- g1 g2) 2)
|
rlm@1
|
97 (expt (- b1 b2) 2)) 0.5))
|
rlm@1
|
98
|
rlm@1
|
99 (defn b&w
|
rlm@1
|
100 "turn everything strictly black or white"
|
rlm@1
|
101 [window]
|
rlm@1
|
102 (with-meta
|
rlm@1
|
103 (zipmap
|
rlm@1
|
104 (keys window)
|
rlm@1
|
105 (map (fn [rgb]
|
rlm@1
|
106 (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black))
|
rlm@1
|
107 black white))
|
rlm@1
|
108 (vals window))) (meta window)))
|
rlm@1
|
109
|
rlm@1
|
110
|
rlm@1
|
111
|
rlm@3
|
112 (defn raster-preamble []
|
rlm@3
|
113 (str-join \newline
|
rlm@3
|
114 ["M63 P0\nG61"
|
rlm@3
|
115 (str \F feed)
|
rlm@3
|
116 "M101"
|
rlm@3
|
117 "M3 S1"]))
|
rlm@3
|
118
|
rlm@4
|
119 (defn raster-epilogue []
|
rlm@4
|
120 (str-join \newline
|
rlm@4
|
121 ["M63 PO"
|
rlm@4
|
122 "M5"
|
rlm@4
|
123 "M2"]))
|
rlm@3
|
124
|
rlm@1
|
125
|
rlm@4
|
126 (defn raster-comment [string]
|
rlm@4
|
127 (str "(" (re-gsub #"[()]" "" string) ")"))
|
rlm@1
|
128
|
rlm@4
|
129 (defn filter-keys [fun m]
|
rlm@4
|
130 (select-keys m (filter fun (keys m))))
|
rlm@2
|
131
|
rlm@4
|
132 (defn filter-vals [fun m]
|
rlm@4
|
133 (into {} (filter (comp fun val) m)))
|
rlm@2
|
134
|
rlm@1
|
135
|
rlm@1
|
136
|
rlm@1
|
137
|
rlm@1
|
138
|
rlm@1
|
139
|
rlm@1
|
140
|
rlm@1
|
141
|
rlm@1
|
142
|
rlm@1
|
143
|
rlm@0
|
144 (defn frame-hash->bufferedImage
|
rlm@0
|
145 [frame-hash]
|
rlm@0
|
146 (let [data (meta frame-hash)
|
rlm@0
|
147 image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)]
|
rlm@0
|
148
|
rlm@0
|
149 (doall (for [element frame-hash]
|
rlm@0
|
150 (let [coord (key element)
|
rlm@0
|
151 rgb (val element)
|
rlm@0
|
152 packed-RGB
|
rlm@0
|
153 (+ (bit-shift-left (:r rgb) 16)
|
rlm@0
|
154 (bit-shift-left (:g rgb) 8)
|
rlm@0
|
155 (:b rgb))]
|
rlm@0
|
156 (.setRGB image (first coord) (last coord) packed-RGB))))
|
rlm@0
|
157 image))
|
rlm@0
|
158
|
rlm@0
|
159
|
rlm@0
|
160
|