Javascript ClojureScript:从ImagaData获取平均RGBA颜色

Javascript ClojureScript:从ImagaData获取平均RGBA颜色,javascript,canvas,clojurescript,Javascript,Canvas,Clojurescript,我试图在ClojureScript中编写一个函数,它返回给定ImageData对象的平均RGBA值 在JavaScript中,使用“for”或“while”循环解决此问题的实现非常快。在毫秒内,它们返回平均值,例如4000 x 4000大小的ImageData对象 在ClojureScript中,我的解决方案并没有那么快,有时浏览器会放弃生成“堆栈跟踪错误” 然而,到目前为止,我写得最快的是: (extend-type js/Uint8ClampedArray ISeqable

我试图在ClojureScript中编写一个函数,它返回给定ImageData对象的平均RGBA值

在JavaScript中,使用“for”或“while”循环解决此问题的实现非常快。在毫秒内,它们返回平均值,例如4000 x 4000大小的ImageData对象

在ClojureScript中,我的解决方案并没有那么快,有时浏览器会放弃生成“堆栈跟踪错误”

然而,到目前为止,我写得最快的是:

(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)))))
不幸的是,它只适用于500x500左右的值,这是不可接受的


我在问自己这里到底有什么问题。为了在ClojureScript中编写一个适当快速的平均颜色函数,我必须参加什么

问题在于您定义的函数是递归的。我不擅长clojurescript,所以我不会告诉您如何在代码中解决问题,而是在概念上解决问题

您需要将问题分解为更小的递归单元。因此,减少像素行以获得每行的结果,然后减少行结果。这将防止递归溢出javascript中的调用堆栈

至于速度,这将取决于你希望结果的准确性,我将使用随机样本随机选择10%的像素,并使用该结果的平均值

您也可以只使用硬件将图像缩放一半,启用平滑进行渲染,然后再次减半,直到有一个像素并使用该像素的值。这将给你一个像素值的平均值,速度非常快,但只是一个值的意思,而不是光子的意思


我将指出,RGB通道的值是对数的,表示捕获(用于照片)或发射(通过屏幕)的光子计数的平方根。因此,像素值的平均值远低于光子计数的平均值。要获得正确的平均值,您必须获得每个通道的平方平均值,然后获得平均值的平方根,使其回到用于RGB值的对数刻度。

好问题。我会看一看来源。我怀疑@mikera编写了这个库,并且非常活跃,所以他将是最好的一个为您解答这个问题的人。但是答案将在一个函数中,比如从这里获取像素:。我怀疑问题在于你没有提前编译所有的东西,所以所有的Clojure的东西都是随身携带的。您希望它在运行时是一个Java程序。