通过 Ring 处理程序提供 BufferedImage

Ant*_*ald 4 bufferedimage clojure ring

我正在寻找一种方法让环形服务器 - 通过请求 - 从 URL 中获取图像,处理它并提供修改后的版本。

这是我到目前为止的方式:

(require '[clj-http.client :as client]
         '[ring.adapter.jetty :refer [run-jetty])
(import javax.imageio.ImageIO)

(def handler (-> (client/get "http://.../some-img.jpg" {:as :stream})
                 :body
                 ImageIO/read
                 .. ;; do some processing with the BufferedImage here
                 .. ;; and serve the modified version))

(run-jetty handler {:port 55555})
Run Code Online (Sandbox Code Playgroud)

特别是我在执行线程宏中的最后一步时遇到了麻烦。

Pio*_*dyl 5

要将字节作为 Ring 中的响应返回,您需要提供java.io.Filejava.io.InputStream作为正文内容:

(defn jpeg-response [image-data]
  (-> image-data
    (ring.util.response/response)
    (ring.util.response/content-type "image/jpeg")))
Run Code Online (Sandbox Code Playgroud)

我还没有找到一种无需创建中间字节数组即可直接获取InputStreamfrom的方法BufferedImage。也许这是 Java Image API 的一个限制,因为实现“拉”方法以获取所需格式的图像字节流所需的复杂性。

相反,有一个“推送”API,其中ImageIO.write方法需要某种图像字节输出。它可能是一个java.io.Filejava.io.OutputStream。因此,您需要首先将字节存储在某处(java.io.Filejava.io.ByteArrayOutputStream),然后将它们用作响应正文:

使用文件(因此首先将图像存储在磁盘上 - 您需要记住清理它):

(let [image (ImageIO/read "...")
      image-file (java.io.File. "...")]
  (ImageIO/write image "jpg" image-file)
  (jpeg-response image-file))
Run Code Online (Sandbox Code Playgroud)

内存字节数组:

(let [image (ImageIO/read "...")
      image-output-stream (ByteArrayOutputStream.)]
  (ImageIO/write image "jpg" image-output-stream)
  (jpeg-response (ByteArrayInputStream. (.toByteArray image-output-stream))))
Run Code Online (Sandbox Code Playgroud)