Clojure 通过环处理程序为BuffereImage提供服务
我正在寻找一种方法,让一个环服务器-通过请求-从一个URL抓取一个图像,处理它,并提供修改后的版本 我就是这样走到现在的:Clojure 通过环处理程序为BuffereImage提供服务,clojure,bufferedimage,ring,Clojure,Bufferedimage,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 :str
(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})
尤其是我在执行线程宏中的最后一步时遇到问题。要返回字节作为环中的响应,您需要提供以下内容之一作为正文内容:
(defn jpeg-response [image-data]
(-> image-data
(ring.util.response/response)
(ring.util.response/content-type "image/jpeg")))
我还没有找到不创建中间字节数组就直接从buffereImage
获取InputStream
的方法。这可能是Java图像API的一个限制,因为实现“拉”方法以获得所需格式的图像字节流所需的复杂性
相反,有一个“push”API,其中ImageIO.write
方法需要某种类型的图像字节输出。它可能是java.io.File
或java.io.OutputStream
。因此,您需要首先将字节存储在某个位置(java.io.File
或java.io.ByteArrayOutputStream
),然后将它们用作响应主体:
使用文件(因此首先将映像存储在磁盘上-您需要记住清理它):
内存中字节数组:
(let [image (ImageIO/read "...")
image-output-stream (ByteArrayOutputStream.)]
(ImageIO/write image "jpg" image-output-stream)
(jpeg-response (ByteArrayInputStream. (.toByteArray image-output-stream))))
可以通过添加一些中间件来解决这个问题吗?这些中间件找到一个函数作为响应的:body部分,尝试调用该函数并将其传递给OutputStream(即要将图像写入的流)?我对Ring的使用经验很少(较少使用中间件),但我使用内部BuffereImage池库和(也是内部的)受Ring启发的web层做了类似的事情——只是都是Java。在我的例子中,它通常是相同的图像,复制到池图像“绘制”,然后流式传输到客户端,从来没有作为文件存在过。最后一行中的键入应该是
ByteArrayInputStream。
(末尾有一个点)。
(let [image (ImageIO/read "...")
image-output-stream (ByteArrayOutputStream.)]
(ImageIO/write image "jpg" image-output-stream)
(jpeg-response (ByteArrayInputStream. (.toByteArray image-output-stream))))