Mercurial > lasercutter
view src/laser/rasterize.clj @ 7:5e167f275a93
moving to rt, hopefully I can do stuff now
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 20 Aug 2010 06:53:41 -0400 |
parents | 4ae2497acf7d |
children | 0f48db8d2a05 |
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)18 (use 'clojure.contrib.combinatorics)21 (use 'clojure.contrib.repl-utils)23 (set! *print-length* 20)26 (def img "/home/r/graster/test.png")29 (def feed 120)30 (def dpi [500, 500])31 (def on_range [0.0, 0.5])32 (def overshoot 0.5)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)42 (defn preserve-meta [f]43 (fn [& x] (with-meta44 (apply f x)45 (meta (last x)))))49 (defn frame-hash50 "yields a convienent representation for the pixles in an image.51 Because of the size of the structvre generated, this must only be used52 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-meta56 (let [buf (.. image+ getBufferedImage)57 color (.getColorModel buf)]58 (apply hash-map59 (interleave60 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]61 (vector x y)))62 (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]63 (let [data (.getRGB buf x y)]64 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)65 :g (bit-shift-right (bit-and 0x00ff00 data) 8)66 :b (bit-and 0x0000ff data))))))))67 {:width (.getWidth image+) :height (.getHeight image+)})))75 (def white {:r 255, :g 255, :b 255})76 (def black {:r 0, :g 0, :b 0})78 (def expt #(Math/pow %1 %2))80 (defn rgb-euclidian81 [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]82 (expt (+ (expt (- r1 r2) 2)83 (expt (- g1 g2) 2)84 (expt (- b1 b2) 2)) 0.5))86 (defn b&w87 "turn everything strictly black or white"88 [window]89 (with-meta90 (zipmap91 (keys window)92 (map (fn [rgb]93 (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black))94 black white))95 (vals window))) (meta window)))99 (defn raster-preamble []100 (str-join \newline101 ["M63 P0\nG61"102 (str \F feed)103 "M101"104 "M3 S1"]))106 (defn raster-epilogue []107 (str-join \newline108 ["M63 PO"109 "M5"110 "M2"]))113 (defn raster-comment [string]114 (str "(" (re-gsub #"[()]" "" string) ")"))116 (defn filter-keys [fun m]117 (select-keys m (filter fun (keys m))))119 (def filter-keys (preserve-meta filter-keys))121 (defn filter-vals [fun m]122 (into {} (filter (comp fun val) m)))124 (def filter-vals (preserve-meta filter-vals))126 (defn frame-hash->bufferedImage127 [frame-hash]128 (let [data (meta frame-hash)129 image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)]131 (doall (for [element frame-hash]132 (let [coord (key element)133 rgb (val element)134 packed-RGB135 (+ (bit-shift-left (:r rgb) 16)136 (bit-shift-left (:g rgb) 8)137 (:b rgb))]138 (.setRGB image (first coord) (last coord) packed-RGB))))139 image))141 (defmulti display "Creates a JFrame and displays a buffered image" class)143 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil))))145 (defn select-row [x window]146 (filter-keys (comp (partial = x) first) window))150 (defmethod display151 BufferedImage [image]152 (let [panel (makePanel image)153 frame (JFrame. "Oh Yeah!")]154 (.add frame panel)155 (.pack frame)156 (.setVisible frame true )157 (.setSize frame(.getWidth image) (.getHeight image))))159 (defmethod display160 ImagePlus [image]161 (display (.getBufferedImage image)))163 (defmethod display164 clojure.lang.PersistentHashMap [frame-hash]165 (display (frame-hash->bufferedImage frame-hash)))167 (defmethod display168 clojure.lang.PersistentArrayMap [frame-hash]169 (display (frame-hash->bufferedImage frame-hash)))175 ;this is a sequence of rows177 ;(defn span [row]178 ; (let [sorted-row (sort #(< (first %1) (first %2)) row)]179 ; (vector (first sorted-row) (last sorted-row))))182 (defn row->gcode [[x-dpi y-dpi] row]183 (let [[x1 y1] (first row)184 [x2 y2] (last row)]185 (str (format "GO X%.3f Y%.3f\n"186 (float (* x1 (/ x-dpi)))187 (float (* y1 (/ y-dpi))))189 (format "G1 X%.3f Y%.3f\n"190 (float (* x2 (/ x-dpi)))191 (float (* y2 (/ y-dpi)))))))193 (defn gather-row [row]194 (let [base [[(first (first row)) (first (first row))]]]195 ; (println base)196 (reduce197 (fn colapse [collection new-n]199 (let [collection (apply vector collection)200 prevoius (last (last collection))201 range-start (first (last collection))]202 ; (println new-n)203 ; (println prevoius)204 ; (println range-start)205 (if (<= new-n (+ prevoius 1))206 (do ;(println "join")207 ;(println (butlast collection))208 (conj (apply vector (butlast collection)) (vector range-start new-n)))209 (conj collection (vector new-n new-n)))))211 base212 (map first row))))216 (defn row->gmask [[x-dpi y-dpi] forward? row]218 (let [start (float (* (/ x-dpi) (first (first row))))]220 (let [preamble (if forward?221 (str222 (format "0 0 0 %.3f\n" start)223 (format "0 0 1 %.3f\n" start)))224 body225 (for [[x y] (gather-row row)]226 (let [x (float (* x (/ x-dpi)))227 y (float (* y (/ x-dpi)))]228 (if forward?229 (str (format "0 0 1 %.3f\n" x)230 (format "0 1 1 %.3f\n" y))232 (str (format "0 0 0 %.3f\n" x)233 (format "0 1 0 %.3f\n" y)))))]235 (str preamble (str-join "" body)))))239 (defn make-rows [pic]241 (map (partial sort #(< (first %1) (first %2)))242 (partition-by last243 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))244 (map first (filter-vals (partial = black) pic))))))249 ;sequence of numbers indicating width250 (def mega252 ;sequence of rows254 (map (partial sort #(< (first %1) (first %2)))255 (partition-by last256 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))257 (map first (filter-vals (partial = black) pic))))))262 (defn generate-gmask [pic]264 (str "1 0 0 0\n"265 (str-join "" (map (fn [[index row]] (row->gmask dpi (even? index) row)) (indexed (make-rows pic))))))268 (defn generate-gcode [pic]269 (str-join "" (map (partial row->gcode dpi) (make-rows pic))))