rlm@0: (ns rlm.image-utils rlm@0: (:import [javax.swing JFrame] rlm@0: [java.awt Color BorderLayout] rlm@0: [ij ImagePlus IJ] rlm@0: [java.lang Math] rlm@0: [java.awt Graphics2D Panel] rlm@0: [ij Macro] rlm@0: [java.io BufferedReader InputStreamReader] rlm@0: [java.awt.image BufferedImage]) rlm@0: (:use [clojure.contrib rlm@0: [math] rlm@0: [def]])) rlm@0: rlm@0: rlm@0: (defmulti frame-hash-multi class) rlm@0: rlm@0: (defmethod frame-hash-multi ImagePlus rlm@0: [image+] rlm@0: (with-meta rlm@0: (let [buf (.. image+ getBufferedImage) rlm@0: color (.getColorModel buf)] rlm@0: (apply hash-map rlm@0: (interleave rlm@0: (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))] rlm@0: (vector x y))) rlm@0: (doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))] rlm@0: (let [data (.getRGB buf x y)] rlm@0: (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16) rlm@0: :g (bit-shift-right (bit-and 0x00ff00 data) 8) rlm@0: :b (bit-and 0x0000ff data)))))))) rlm@0: {:width (.getWidth image+) :height (.getHeight image+)})) rlm@0: rlm@0: (defmethod frame-hash-multi String rlm@0: [image-name] rlm@0: (let [image+ (ImagePlus. image-name)] rlm@0: (frame-hash-multi image+))) rlm@0: rlm@0: (defn frame-hash rlm@0: "yields a convienent representation for the pixles in an image. rlm@0: Because of the size of the structvre generated, this must only be used rlm@0: in a transient way so that java can do it's garbage collection." rlm@0: [something] rlm@0: (frame-hash-multi something)) rlm@0: rlm@0: rlm@0: (def white {:r 255, :g 255, :b 255}) rlm@0: (def black {:r 0, :g 0, :b 0}) rlm@0: rlm@0: (defn rgb-euclidian rlm@0: [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ] rlm@0: (expt (+ (expt (- r1 r2) 2) rlm@0: (expt (- g1 g2) 2) rlm@0: (expt (- b1 b2) 2)) 0.5)) rlm@0: rlm@0: (defn b&w rlm@0: "turn everything strictly black or white" rlm@0: [window] rlm@0: (with-meta rlm@0: (zipmap rlm@0: (keys window) rlm@0: (map (fn [rgb] rlm@0: (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black)) rlm@0: black white)) rlm@0: (vals window))) (meta window))) rlm@0: rlm@0: (defn frame-hash->bufferedImage rlm@0: [frame-hash] rlm@0: (let [data (meta frame-hash) rlm@0: image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)] rlm@0: rlm@0: (doall (for [element frame-hash] rlm@0: (let [coord (key element) rlm@0: rgb (val element) rlm@0: packed-RGB rlm@0: (+ (bit-shift-left (:r rgb) 16) rlm@0: (bit-shift-left (:g rgb) 8) rlm@0: (:b rgb))] rlm@0: (.setRGB image (first coord) (last coord) packed-RGB)))) rlm@0: image)) rlm@0: rlm@0: (defmulti display "Creates a JFrame and displays a buffered image" class) rlm@0: rlm@0: (defn- makePanel [image] rlm@0: (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil)))) rlm@0: rlm@0: (defmethod display rlm@0: BufferedImage [image] rlm@0: (let [panel (makePanel image) rlm@0: frame (JFrame. "Oh Yeah!")] rlm@0: (.add frame panel) rlm@0: (.pack frame) rlm@0: (.setVisible frame true ) rlm@0: (.setSize frame(.getWidth image) (.getHeight image)))) rlm@0: rlm@0: (defmethod display rlm@0: ImagePlus [image] rlm@0: (display (.getBufferedImage image))) rlm@0: rlm@0: (defmethod display rlm@0: clojure.lang.PersistentHashMap [frame-hash] rlm@0: (display (frame-hash->bufferedImage frame-hash))) rlm@0: rlm@0: (defmethod display rlm@0: clojure.lang.PersistentArrayMap [frame-hash] rlm@0: (display (frame-hash->bufferedImage frame-hash))) rlm@0: rlm@0: (defn rotate [degrees #^ImagePlus image] rlm@0: (.rotate (.getChannelProcessor image) degrees) rlm@0: image) rlm@0: rlm@0: rlm@0: (defn-memo width [pic] rlm@0: (inc (first (last (sort (fn [[x0 y0] [x1 y1]] (> x1 x0)) (keys pic)))))) rlm@0: rlm@0: (defn-memo height [pic] rlm@0: (inc (last (last (sort (fn [[x0 y0] [x1 y1]] (> y1 y0)) (keys pic)))))) rlm@0: