Advertisement
Guest User

Untitled

a guest
Jun 15th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns hello.core
  2.   (:import (java.awt.image BufferedImage)
  3.            (java.awt Color)
  4.            (javax.imageio ImageIO)
  5.            (java.io File)))
  6.  
  7. (def clojure-img (File. "images/clojure.jpg"))
  8.  
  9. (defn get-pixels [^java.awt.image.BufferedImage img]
  10.   (let [cord-rgb-pairs (for [x (range (.getWidth img))
  11.                              y (range (.getHeight img))]
  12.                          (let [c (Color. (.getRGB img x y))]
  13.                            [[x y] [(.getRed c) (.getGreen c) (.getBlue c)]]))]
  14.     (reduce (fn [state [key value]]
  15.               (assoc state key value))
  16.             {}
  17.             cord-rgb-pairs)))
  18.  
  19. (defn characters []
  20.   (into [] (map char (range 33 256))))
  21.  
  22. (defn mask-to-value
  23.   [range-value mask]
  24.   (reduce (fn [state [value pow]]
  25.             (+ state (* value (Math/pow range-value pow))))
  26.           0
  27.           (map vector mask (reverse (range (count mask))))))
  28.  
  29. (defn merge-values2
  30.   [max & values]
  31.   (/ (apply + values)
  32.      (* (dec max) (count values))))
  33.  
  34. ;9
  35. ;0 0 - 0/9
  36. ;1 0 - 1/9
  37. ;2 0 - 2/9
  38. ;0 1 - 3/9
  39. ;1 1 - 4/9
  40. ;2 1 - 5/9
  41. ;0 2 - 6/9
  42. ;1 2 - 7/9
  43. ;2 2 - 8/9
  44. (merge-values2 3 1 2)
  45. (merge-values2 3 2 1)
  46.  
  47. (defn get-near
  48.   [[x y] radius]
  49.   (when (and (>= radius 1)
  50.              (odd? radius))
  51.     (let [size (int (/ radius 2))]
  52.       (for [nx (map (partial - size) (range radius))
  53.             ny (map (partial - size) (range radius))]
  54.         [(+ x nx) (+ y ny)]))))
  55.  
  56. (defn padding-range
  57.   ([padding count step] (range padding (- count padding) step))
  58.   ([padding count] (padding-range padding count 1)))
  59.  
  60.  
  61. (defn value-to-char
  62.   [value chars]
  63.   (let [freq (/ 1.0001 (count chars))
  64.         index (int (/ value freq))]
  65.     (get chars (int (/ value freq)))))
  66.  
  67. (defn avg-rgb [rgbs]
  68.   (let [rgb-count (count rgbs)]
  69.     (->> (reduce #(map + %1 %2) rgbs)
  70.          (map #(int (/ % rgb-count))))))
  71.  
  72. (defn cord-to-ascii
  73.   [cord pixels radius]
  74.   (let [region (get-near cord radius)
  75.         rgb-region (remove nil? (map #(get pixels %) region))
  76.         average-region-rgb (avg-rgb rgb-region)
  77.         avg-value (apply (partial merge-values2 256) average-region-rgb)]
  78.     (value-to-char avg-value (characters))))
  79.  
  80. (defn image-to-ascii
  81.   [filename radius step]
  82.   (let [bitmap (ImageIO/read (File. filename))
  83.         image-pixels (get-pixels bitmap)
  84.         height (.getHeight bitmap)
  85.         width (.getWidth bitmap)
  86.         ascii-matrix (for [x (padding-range radius width step)
  87.                            y (padding-range radius height step)]
  88.                        [[(int (/ x step)) (int (/ y step))] (cord-to-ascii [x y] image-pixels radius)])]
  89.     (reduce (fn [state [key value]]
  90.               (assoc state key value))
  91.             {}
  92.             ascii-matrix)))
  93.  
  94. (defn print-map
  95.   [cord-chars]
  96.   (let [cords (keys cord-chars)
  97.         height (inc (apply max (map second cords)))
  98.         width (inc (apply max (map first cords)))]
  99.     (reduce (fn [ystate y]
  100.               (let [line (reduce (fn [xstate x]
  101.                                    (str xstate (get cord-chars [x y])))
  102.                                  ""
  103.                                  (range width))]
  104.                 (str ystate \newline line)))
  105.             ""
  106.             (range height))))
  107.  
  108. (defn image-to-ascii-file
  109.   [input radius step output]
  110.   (let [image-cord-char-map (image-to-ascii input radius step)]
  111.     (with-open [w (clojure.java.io/writer output)]
  112.       (.write w (print-map image-cord-char-map)))))
  113.  
  114. (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