【问题标题】:Serve a BufferedImage by a Ring handler由 Ring 处理程序提供 BufferedImage
【发布时间】:2016-06-04 10:16:24
【问题描述】:

我正在寻找一种方法让响铃服务器根据请求从 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})

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

【问题讨论】:

  • 是否可以通过添加一些中间件来解决这个问题,该中间件找到一个函数作为响应的 :body 部分,并尝试调用该函数并将其传递给 OutputStream(即写入图像的流)?我对 Ring 的经验很少(较少使用中间件),但我使用内部 BufferedImage 池库和(也是内部的)Ring-inspired web-tier 做了类似的事情 - 只是它全部使用 Java。在我的情况下,它通常是相同的图像,它被复制到池图像,“绘制”,然后流式传输到客户端,从未作为文件存在。

标签: clojure bufferedimage ring


【解决方案1】:

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

(defn jpeg-response [image-data]
  (-> image-data
    (ring.util.response/response)
    (ring.util.response/content-type "image/jpeg")))

我还没有找到直接从BufferedImage 获取InputStream 而不创建中间字节数组的方法。这可能是 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))

内存字节数组:

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

【讨论】:

  • 最后一行的错字,应该是ByteArrayInputStream.(末尾有一个点)。
猜你喜欢
  • 2015-04-16
  • 2011-12-19
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 2014-11-07
  • 2015-05-08
  • 2021-09-11
  • 2020-01-23
相关资源
最近更新 更多