first pass at performance tweaks. work with a direct int[] of pixels
This commit is contained in:
parent
f62a2ca558
commit
5baeadb0f5
|
@ -1,7 +1,7 @@
|
||||||
(ns toascii.models.image
|
(ns toascii.models.image
|
||||||
"Largely based on the Claskii library: https://github.com/LauJensen/Claskii"
|
"Largely based on the Claskii library: https://github.com/LauJensen/Claskii"
|
||||||
(:import (java.awt RenderingHints Graphics2D Image)
|
(:import (java.awt RenderingHints Graphics2D Image)
|
||||||
(java.awt.image BufferedImage)
|
(java.awt.image BufferedImage Raster)
|
||||||
(javax.imageio ImageIO)
|
(javax.imageio ImageIO)
|
||||||
(java.io File))
|
(java.io File))
|
||||||
(:require [clojure.string :as str]
|
(:require [clojure.string :as str]
|
||||||
|
@ -12,46 +12,43 @@
|
||||||
(def ascii-chars [\# \A \@ \% \$ \+ \= \* \: \, \. \space])
|
(def ascii-chars [\# \A \@ \% \$ \+ \= \* \: \, \. \space])
|
||||||
(def num-ascii-chars (count ascii-chars))
|
(def num-ascii-chars (count ascii-chars))
|
||||||
|
|
||||||
(defn- get-css-color-attr [r g b]
|
(defn- add-pixel [argb ^StringBuilder sb color?]
|
||||||
(format "color: #%02x%02x%02x;" r g b))
|
(let [r (bit-shift-right (bit-and 0x00ff0000 argb) 16)
|
||||||
|
g (bit-shift-right (bit-and 0x0000ff00 argb) 8)
|
||||||
(defn- get-color-brightness [r g b]
|
b (bit-and 0x000000ff argb)
|
||||||
(int
|
peak (int
|
||||||
(Math/sqrt
|
(Math/sqrt
|
||||||
(+ (* r r 0.241)
|
(+ (* r r 0.241)
|
||||||
(* g g 0.691)
|
(* g g 0.691)
|
||||||
(* b b 0.068)))))
|
(* b b 0.068))))
|
||||||
|
|
||||||
(defn- get-pixel [^BufferedImage image x y]
|
|
||||||
(let [argb (.getRGB image x y)]
|
|
||||||
[(bit-shift-right (bit-and 0xff000000 argb) 24)
|
|
||||||
(bit-shift-right (bit-and 0x00ff0000 argb) 16)
|
|
||||||
(bit-shift-right (bit-and 0x0000ff00 argb) 8)
|
|
||||||
(bit-and 0x000000ff argb)]))
|
|
||||||
|
|
||||||
(defn- get-ascii-pixel [^BufferedImage image x y color?]
|
|
||||||
(let [[a r g b] (get-pixel image x y)
|
|
||||||
peak (get-color-brightness r g b)
|
|
||||||
char-index (if (zero? peak)
|
char-index (if (zero? peak)
|
||||||
(dec num-ascii-chars)
|
(dec num-ascii-chars)
|
||||||
(dec (int (* num-ascii-chars (/ peak 255)))))
|
(dec (int (* num-ascii-chars (/ peak 255)))))
|
||||||
pixel-char (nth ascii-chars (if (pos? char-index) char-index 0))]
|
pixel-char (nth ascii-chars (if (pos? char-index) char-index 0))]
|
||||||
(if color?
|
(if color?
|
||||||
[:span {:style (get-css-color-attr r g b)} pixel-char]
|
; <span style="color: rgb(255, 255, 255);">X</span>
|
||||||
|
(doto sb
|
||||||
|
(.append "<span style=\"color: rgb(")
|
||||||
|
(.append r)
|
||||||
|
(.append ",")
|
||||||
|
(.append g)
|
||||||
|
(.append ",")
|
||||||
|
(.append b)
|
||||||
|
(.append ");\">")
|
||||||
|
(.append pixel-char)
|
||||||
|
(.append "</span>"))
|
||||||
pixel-char)))
|
pixel-char)))
|
||||||
|
|
||||||
(defn- pixels->ascii [^BufferedImage image color?]
|
(defn- pixels->ascii [^BufferedImage image color?]
|
||||||
(let [width (.getWidth image)
|
(let [width (.getWidth image)
|
||||||
ascii-image (for [y (range (.getHeight image))
|
height (.getHeight image)
|
||||||
x (range (.getWidth image))]
|
sb (StringBuilder.)
|
||||||
(get-ascii-pixel image x y color?))
|
pixels (.getDataElements (.getRaster image) 0 0 width height nil)]
|
||||||
output (->> ascii-image
|
(dotimes [y height]
|
||||||
(partition width)
|
(dotimes [x width]
|
||||||
(map #(conj % (if color? [:br] \newline)))
|
(add-pixel (aget pixels (+ x (* y width))) sb color?))
|
||||||
(apply concat))]
|
(.append sb (if color? "<br>" \newline)))
|
||||||
(if color?
|
(.toString sb)))
|
||||||
(html output)
|
|
||||||
(str/join output))))
|
|
||||||
|
|
||||||
(defn get-image-by-url
|
(defn get-image-by-url
|
||||||
(^BufferedImage [^String url]
|
(^BufferedImage [^String url]
|
||||||
|
@ -97,4 +94,19 @@
|
||||||
(pixels->ascii final-image color?))))
|
(pixels->ascii final-image color?))))
|
||||||
|
|
||||||
(defn wrap-pre-tag [s]
|
(defn wrap-pre-tag [s]
|
||||||
(str "<pre style=\"font-size:6pt; letter-spacing:1px; line-height:5pt; font-weight:bold;\">" s "</pre>"))
|
(str "<pre style=\"font-size:6pt; letter-spacing:1px; line-height:5pt; font-weight:bold;\">" s "</pre>"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#_(require '[criterium.core :as c])
|
||||||
|
|
||||||
|
#_(c/bench
|
||||||
|
(let [f (File. "./test/images/test.png")
|
||||||
|
image (get-image-by-file f)
|
||||||
|
ascii (convert-image image true)]
|
||||||
|
(count ascii)))
|
||||||
|
|
||||||
|
#_(let [f (File. "./test/images/test.png")
|
||||||
|
image (get-image-by-file f)
|
||||||
|
ascii (convert-image image true)]
|
||||||
|
(count ascii))
|
Reference in a new issue