Mercurial > lasercutter
view src/laser/rasterize.clj @ 14:db745c95aabd
trying to revert back to a usable form
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 29 Aug 2010 00:09:28 -0400 |
parents | 397ab24b4952 |
children | 8ad629298649 |
line wrap: on
line source
1 (ns laser.rasterize)3 (import '(java.io File))4 (import '(org.apache.commons.io FileUtils))5 (import '(javax.imageio ImageIO) )6 (import '(javax.swing JFrame))7 (import '(java.awt Color BorderLayout))8 (import '(ij ImagePlus IJ))9 (import '(java.lang Math))10 (import '(java.awt Graphics2D Panel))11 (import '(ij Macro))13 (import '(java.io BufferedReader InputStreamReader))14 (import '(java.awt.image BufferedImage))16 ;(use 'clojure.contrib.str-utils)17 ;(use 'clojure.contrib.seq-utils)18 ;(use 'clojure.contrib.combinatorics)19 ;(use 'clojure.contrib.duck-streams)21 ;(use 'clojure.contrib.repl-utils)23 ;(set! *print-length* 20)28 (def feed 120)29 (def dpi [500, 500])34 (defn preserve-meta [f]35 (fn [& x] (with-meta36 (apply f x)37 (meta (last x)))))39 (defmulti frame-hash-multi class)42 (defmethod frame-hash-multi ImagePlus43 [image+]44 (with-meta45 (let [buf (.. image+ getBufferedImage)46 color (.getColorModel buf)]47 (apply hash-map48 (interleave49 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]50 (vector x y)))51 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]52 (let [data (.getRGB buf x y)]53 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)54 :g (bit-shift-right (bit-and 0x00ff00 data) 8)55 :b (bit-and 0x0000ff data))))))))56 {:width (.getWidth image+) :height (.getHeight image+)}))59 (defmethod frame-hash-multi String60 [image-name]61 (let [image+ (ImagePlus. image-name)]62 (frame-hash-multi image+)))65 (defn frame-hash66 "yields a convienent representation for the pixles in an image.67 Because of the size of the structvre generated, this must only be used68 in a transient way so that java can do it's garbage collection."69 [something]70 (frame-hash-multi something))72 ;(def frame-hash (preserve-meta frame-hash))77 (def white {:r 255, :g 255, :b 255})78 (def black {:r 0, :g 0, :b 0})82 (defn rgb-euclidian83 [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]84 (expt (+ (expt (- r1 r2) 2)85 (expt (- g1 g2) 2)86 (expt (- b1 b2) 2)) 0.5))88 (defn b&w89 "turn everything strictly black or white"90 [window]91 (with-meta92 (zipmap93 (keys window)94 (map (fn [rgb]95 (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black))96 black white))97 (vals window))) (meta window)))101 (defn raster-preamble []102 (str-join \newline103 ["M63 P0\nG61"104 (str \F feed)105 "M101"106 "M3 S1\n"]))108 (defn raster-epilogue []109 (str-join \newline110 ["M63 P0"111 "M5"112 "M2\n"]))115 (defn raster-comment [string]116 (str "(" (re-gsub #"[()]" "" string) ")"))118 (defn filter-keys [fun m]119 (select-keys m (filter fun (keys m))))121 (def filter-keys (preserve-meta filter-keys))123 (defn filter-vals [fun m]124 (into {} (filter (comp fun val) m)))126 (def filter-vals (preserve-meta filter-vals))128 (defn frame-hash->bufferedImage129 [frame-hash]130 (let [data (meta frame-hash)131 image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)]133 (doall (for [element frame-hash]134 (let [coord (key element)135 rgb (val element)136 packed-RGB137 (+ (bit-shift-left (:r rgb) 16)138 (bit-shift-left (:g rgb) 8)139 (:b rgb))]140 (.setRGB image (first coord) (last coord) packed-RGB))))141 image))143 (defmulti display "Creates a JFrame and displays a buffered image" class)145 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil))))147 (defn select-row [x window]148 (filter-keys (comp (partial = x) first) window))152 (defmethod display153 BufferedImage [image]154 (let [panel (makePanel image)155 frame (JFrame. "Oh Yeah!")]156 (.add frame panel)157 (.pack frame)158 (.setVisible frame true )159 (.setSize frame(.getWidth image) (.getHeight image))))161 (defmethod display162 ImagePlus [image]163 (display (.getBufferedImage image)))165 (defmethod display166 clojure.lang.PersistentHashMap [frame-hash]167 (display (frame-hash->bufferedImage frame-hash)))169 (defmethod display170 clojure.lang.PersistentArrayMap [frame-hash]171 (display (frame-hash->bufferedImage frame-hash)))177 ;this is a sequence of rows179 ;(defn span [row]180 ; (let [sorted-row (sort #(< (first %1) (first %2)) row)]181 ; (vector (first sorted-row) (last sorted-row))))185 (defn row->gcode [[x-dpi y-dpi] forward? row]187 (let [[x1 y1] (if forward? (last row) (first row))188 [x2 y2] (if forward? (first row) (last row))]191 ; (let [[x1 y1] (first row)192 ; [x2 y2] (last row)193 ; x2 (+ x2 (* x-dpi 0.318))]196 ; (println x2)197 (str (format "G0 X%.3f Y%.3f\n"198 (float (* x1 (/ x-dpi)))199 (float (* y1 (/ y-dpi))))201 (format "G1 X%.3f Y%.3f\n"202 (float (* x2 (/ x-dpi)))203 (float (* y2 (/ y-dpi)))))))205 (defn gather-row [row]206 (let [base [[(first (first row)) (first (first row))]]]207 ; (println base)208 (reduce209 (fn colapse [collection new-n]211 (let [collection (apply vector collection)212 prevoius (last (last collection))213 range-start (first (last collection))]214 ; (println new-n)215 ; (println prevoius)216 ; (println range-start)217 (if (<= new-n (+ prevoius 1))218 (do ;(println "join")219 ;(println (butlast collection))220 (conj (apply vector (butlast collection))221 (vector range-start new-n)))222 (conj collection (vector new-n new-n)))))224 base225 (map first row))))230 (defn row->gmask [[x-dpi y-dpi] forward? row]231 ; (println forward?)232 (let [start (float (* (/ x-dpi) (first (first233 (if forward?234 (reverse row) row)))))]236 (let [preamble (if-not forward?237 (format "0 0 0 %.3f\n" start)238 (format "0 0 1 %.3f\n" start))239 body240 (for [[x y]241 (if forward?242 (reverse (gather-row row))243 (gather-row row))]244 (let [x (float (* x (/ x-dpi)))245 y (float (* y (/ x-dpi)))246 ;; x (+ x 0.159)];; shift by a small margin.247 (if-not forward?248 (str (format "0 0 1 %.3f\n" x)249 (format "0 1 1 %.3f\n" y))251 (str (format "0 0 0 %.3f\n" y)252 (format "0 1 0 %.3f\n" x)))))]254 (str preamble (str-join "" body)))))258 (defn make-rows [pic]259 (map (partial sort #(< (first %1) (first %2)))260 (partition-by last261 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))262 (map first (filter-vals (partial = black) pic))))))266 (defn generate-gmask [pic]268 (str "1 0 0 0\n"269 (str-join "" (map (fn [[index row]]270 (row->gmask dpi (even? index) row))271 (indexed (make-rows pic))))))274 ;; 1 0 0 0275 ;; 0 0 1 2.881276 ;; 0 0 0 2.881277 ;; 0 1 0 2.863278 ;; 0 0 0 2.769279 ;; 0 1 0 2.751280 ;; 0 0 0 2.729281 ;; 0 1 0 2.617282 ;; 0 0 0 2.593283 ;; 0 1 0 2.561284 ;; 0 0 0 2.463285 ;; 0 1 0 2.445286 ;; 0 0 0 2.385287 ;; 0 1 0 2.317288 ;; 0 0 0 2.253289 ;; 0 1 0 2.233290 ;; 0 0 0 2.177294 (defn generate-gcode [pic]295 (str (raster-preamble)297 (str-join ""298 (map299 (fn [index row]300 (partial row->gcode dpi (even? index)) (indexed (make-rows pic))))301 (raster-epilogue))))305 ; (str-join "" (map (partial row->gcode dpi) (make-rows pic)))306 ; (raster-epilogue)))310 (defn rotate [degrees #^ImagePlus image]311 (.rotate (.getChannelProcessor image) degrees)312 image)314 (defn map-keys [f m]315 (into {} (map (fn [[key val]] [(f key) val]) m)))319 (defn invert-frame-hash [pic]320 (map-keys (fn [[x y]] [x (- (:height (meta pic)) y 1)]) pic ))323 (defn generate-files [pic]324 (let [image (invert-frame-hash (b&w (frame-hash (rotate 180 (ImagePlus. pic)))))]325 (spit "/home/r/kevin/out.ngc" (generate-gcode image))326 (spit "/home/r/kevin/out.gmask" (generate-gmask image))327 image))331 (defn update-state []332 (def sing "/home/r/lasercutter/graster/signer4laser2x1.png")334 (def pic (frame-hash (let [image (ImagePlus. sing)]335 (.rotate (.getChannelProcessor image) 180)336 image)))338 (def pic (b&w pic)))350 ;;;; testing352 (defn init []353 (let [stuff355 (bound-fn []357 (do358 (println "hi everyone")359 (def img "/home/r/kevin/sing.png")360 (def pic (frame-hash (let [image (ImagePlus. img)]361 (.rotate (.getChannelProcessor image) 180)362 image)))365 (def test-image366 (invert-frame-hash (b&w (frame-hash (rotate 180 (ImagePlus. img))))))368 (defn test-gmask []369 (println (str-join "" (take 170 (generate-gmask test-image)))))371 (println "ALL variables initialized!")373 ))]374 (.start375 (Thread. stuff))))379 (defn thread-test []381 (let [temp *out*]382 (.start383 (Thread.384 (fn []385 (with-bindings {#'*out* temp}386 (Thread/sleep 5000)387 (println "hi")))))))390 (comment391 (do392 (require 'rlm.quick)393 (ns laser.rasterize)394 (rlm.quick/dirty)395 (use :reload-all 'laser.rasterize)396 (undef map-keys)397 (use :reload-all 'laser.rasterize)))