Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns hello.core
- (:import (java.awt.image BufferedImage)
- (java.awt Color)
- (javax.imageio ImageIO)
- (java.io File)))
- (def clojure-img (File. "images/clojure.jpg"))
- (defn get-pixels [^java.awt.image.BufferedImage img]
- (let [cord-rgb-pairs (for [x (range (.getWidth img))
- y (range (.getHeight img))]
- (let [c (Color. (.getRGB img x y))]
- [[x y] [(.getRed c) (.getGreen c) (.getBlue c)]]))]
- (reduce (fn [state [key value]]
- (assoc state key value))
- {}
- cord-rgb-pairs)))
- (defn characters []
- (into [] (map char (range 33 256))))
- (defn mask-to-value
- [range-value mask]
- (reduce (fn [state [value pow]]
- (+ state (* value (Math/pow range-value pow))))
- 0
- (map vector mask (reverse (range (count mask))))))
- (defn merge-values2
- [max & values]
- (/ (apply + values)
- (* (dec max) (count values))))
- ;9
- ;0 0 - 0/9
- ;1 0 - 1/9
- ;2 0 - 2/9
- ;0 1 - 3/9
- ;1 1 - 4/9
- ;2 1 - 5/9
- ;0 2 - 6/9
- ;1 2 - 7/9
- ;2 2 - 8/9
- (merge-values2 3 1 2)
- (merge-values2 3 2 1)
- (defn get-near
- [[x y] radius]
- (when (and (>= radius 1)
- (odd? radius))
- (let [size (int (/ radius 2))]
- (for [nx (map (partial - size) (range radius))
- ny (map (partial - size) (range radius))]
- [(+ x nx) (+ y ny)]))))
- (defn padding-range
- ([padding count step] (range padding (- count padding) step))
- ([padding count] (padding-range padding count 1)))
- (defn value-to-char
- [value chars]
- (let [freq (/ 1.0001 (count chars))
- index (int (/ value freq))]
- (get chars (int (/ value freq)))))
- (defn avg-rgb [rgbs]
- (let [rgb-count (count rgbs)]
- (->> (reduce #(map + %1 %2) rgbs)
- (map #(int (/ % rgb-count))))))
- (defn cord-to-ascii
- [cord pixels radius]
- (let [region (get-near cord radius)
- rgb-region (remove nil? (map #(get pixels %) region))
- average-region-rgb (avg-rgb rgb-region)
- avg-value (apply (partial merge-values2 256) average-region-rgb)]
- (value-to-char avg-value (characters))))
- (defn image-to-ascii
- [filename radius step]
- (let [bitmap (ImageIO/read (File. filename))
- image-pixels (get-pixels bitmap)
- height (.getHeight bitmap)
- width (.getWidth bitmap)
- ascii-matrix (for [x (padding-range radius width step)
- y (padding-range radius height step)]
- [[(int (/ x step)) (int (/ y step))] (cord-to-ascii [x y] image-pixels radius)])]
- (reduce (fn [state [key value]]
- (assoc state key value))
- {}
- ascii-matrix)))
- (defn print-map
- [cord-chars]
- (let [cords (keys cord-chars)
- height (inc (apply max (map second cords)))
- width (inc (apply max (map first cords)))]
- (reduce (fn [ystate y]
- (let [line (reduce (fn [xstate x]
- (str xstate (get cord-chars [x y])))
- ""
- (range width))]
- (str ystate \newline line)))
- ""
- (range height))))
- (defn image-to-ascii-file
- [input radius step output]
- (let [image-cord-char-map (image-to-ascii input radius step)]
- (with-open [w (clojure.java.io/writer output)]
- (.write w (print-map image-cord-char-map)))))
- (image-to-ascii-file "images/cat.jpg" 5 5 "images/cat-jpg-ascii-2.txt")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement