首页 > 解决方案 > (设置!(.-onload image)(fn []))不工作

问题描述

我有以下代码,它将一些图像作为输入,然后使用 compress-omg 函数对其进行压缩,该函数获取按顺序输入的每个图像的数据 url,并将压缩的 blob 存储在 db 向量中:images

(defn image-selector []
  [:<>
   ;; appending image in this div
   [:div {:id "test-div"}]
   [:input {:type "file"
                     :multiple true
                     :id "input-image"
                     :on-change
                     (fn [e]
                         (let [files (array-seq (.. e -target -files))]
                           (doseq [file files]
                             ;; must create a new file-reader in each iteration
                             (let [file-reader (js/FileReader.)]
                               (set! (.-onload file-reader)
                                 (fn [e]
                                   (let [data-url (-> e .-target .-result)]
                                     (dispatch [:images (compress-img data-url)]))))
                               (.readAsDataURL file-reader file)))))}]])


(defn compress-img [data-url]
  "takes data-url. Compresses it and returns a blob."
  (let [image (js/Image.)
        canvas (js/document.createElement "canvas")
        ctx (.getContext canvas "2d")
        blob (js/Blob. [data-url])
        window-url (or (-> js/window .-URL) (-> js/window .-webkitURL ))
        blob-url (.createObjectURL window-url blob)
        ]
    (set! (.-onload image)
;; doesn't print 
          (fn [_]

            (prn "image height" (.-height image))
            (prn "image width " (.-width image))
            (set! (.-src image) blob-url)

            (.appendChild (js/document.getElementById "test-div") image)


            (.drawImage ctx image 0 0 (.-width image) (.-height image))
            ;; approximating sizes of compressed and uncompressed images
            (prn "size original (MB)" (* 0.75 0.000001 (.-length data-url)))
            (prn "size upload (MB)" (* 0.75 0.000001 (.-length (.toDataURL canvas "image/png" 0.1))))
            ;; compressing and returning the blob
            (js/Blob. [(.toDataURL canvas "image/png" 0.1)])
            )

          )
    (set! (.-onerror image)
;; doesn't print
          (fn [e]
            (prn "error is " e)
            (prn "error")))
   ))

但是永远不会触发 onload 和 onerror 事件。我究竟做错了什么?

标签: canvasblobfilereaderclojurescriptonload

解决方案


在您的代码示例中,(set! (.-src image) blob-url)滑入onload事件处理程序本身。

您必须在该函数之外调用它才能真正开始加载图像,以便它可以正确触发onload.

就像是

(set! (.-src image) blob-url)
(set! (.-onload image)
  (fn [_]
    (prn "image height" (.-height image))
    (prn "image width " (.-width image))

    (.appendChild (js/document.getElementById "test-div") image)

    (.drawImage ctx image 0 0 (.-width image) (.-height image))
    ;; approximating sizes of compressed and uncompressed images
    (prn "size original (MB)" (* 0.75 0.000001 (.-length data-url)))
    (prn "size upload (MB)" (* 0.75 0.000001 (.-length (.toDataURL canvas "image/png" 0.1))))
    ;; compressing and returning the blob
    (js/Blob. [(.toDataURL canvas "image/png" 0.1)])
    ))

推荐阅读