我正在尝试使用Clojure Quil库创建一个加载图像到小程序。当我存储加载图像引用并将其与调用一起使用时image
在加载期间它可以工作。但是当我加载并在绘制中显示时,它不起作用。
这有效:
(ns img-demo.core
(:require [quil.core :as q]))
(def img (ref nil))
(def img-url "https://dummyimage.com/100x100/2c3e50/ffffff.png")
(defn setup []
(q/background 0)
(dosync (ref-set img (q/load-image img-url))))
(q/defsketch example
:title "image demo"
:setup setup
:draw #(q/image @img 0 0)
:size [600 600])
这是行不通的,
(ns img-demo.core
(:require [quil.core :as q]))
(def img-url "https://dummyimage.com/100x100/2c3e50/ffffff.png")
(q/defsketch example
:title "image demo"
:draw #(q/image (q/load-image img-url) 0 0)
:size [600 600])
在后一种情况下,我知道load-image
应该在quil.applet/with-applet
内部调用。由于它发生在defsketch
内部,我希望它会自动处理或至少抛出 NPE。为什么它不起作用?
load-image
异步加载图像,因此它在第二个示例中不起作用的原因是,当调用draw
时图像尚未加载。您可以通过在调用image
之前使用loaded?
函数进行分支来检查这一点:
(q/defsketch example
:title "image demo"
:draw #(let [img (q/load-image img-url)]
(if (q/loaded? img)
(q/image img 0 0)
(q/ellipse 100 100 100 100)))
:size [600 600])
运行上面的代码,你会看到一个正在绘制的圆圈,因为img
尚未加载。您也不会收到 Null 指针异常,因为load-image
没有返回nil
- 它只是在调用图像之前没有完成加载图像draw
。因此,发生的一切就是空白画布上没有任何东西被绘制出来。
这就是为什么通常建议在setup
中加载图像(以及您的第一个示例有效的原因(。setup
在draw
之前执行,这保证了在调用draw
时图像已经加载