I'm trying to write a function in ClojureScript, which returns the average RGBA value of a given ImageData Object.
In JavaScript, implementations for this problem with a "for" or "while" loop are very fast. Within milliseconds they return the average of e.g. 4000 x 4000 sized ImageData objects.
In ClojureScript my solutions are not approximately as fast, sometimes the browser gives up yielding "stack trace errors".
However the fastest one I wrote until now is this one:
(extend-type js/Uint8ClampedArray
ISeqable
(-seq [array] (array-seq array 0)))
(defn average-color [img-data]
(let [data (.-data img-data)
nr (/ (count data) 4)]
(->> (reduce (fn [m v] (-> (update-in m [:color (rem (:pos m) 4)] (partial + v))
(update-in [:pos] inc)))
{:color [0 0 0 0] :pos 0}
data)
(:color)
(map #(/ % nr)))))
Well, unfortunately it works only upt to values around 500x500, which is not acceptable.
I'm asking myself what exactly is the problem here. What do I have to attend in order to write a properly fast average-color function in ClojureScript.