呈现一张图片

24

这应该很简单,但是我无法让它工作。

我有一个控制器方法,根据查询找到一张图片,然后将输出缓存。 图片可能是远程的(flickr,google images等),也可能是本地的。 无论来源如何,我只需要获取图像文件内容,并将其传递给用户。 实质上,这就是一个代理。 似乎通过传递远程图片可以正常工作,但是通过传递本地图片会出现:

invalid byte sequence in UTF-8

这是我得到的代码。希望有人可以解决问题,或者指导我用更好的方式编写代码。

def image_proxy
  query = params[:query]
  image_url = get_image_url(query) # returns an absolute local file path or a URL

  response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}"
  response.headers['Content-Type'] = 'image/jpeg'
  response.headers['Content-Disposition'] = 'inline'
  render :text => open(image_url).read
end

远程文件可以正常工作,本地文件无法工作。

奖励任何能够帮助解决另一个问题的人:

  1. 我需要设置正确的内容类型。 远程图像 URL 不告诉我图像类型,我只收到一个 URL,有时该 URL 不包含扩展名。 因此,我选择了 jpeg,因为它似乎可以在发送给我的任何图像类型中正常工作。

谢谢!

2个回答

23

尝试使用render :text => open(image_url, "rb").read,告诉Ruby打开的文件是二进制文件,而不是尝试将其读取为文本。

编辑

对于奖励问题,您可以读取前几个字节并查看它们包含的内容。PNG文件始终以十六进制字节值89 50 4E 47 0D 0A 1A 0A(或十进制值137 80 78 71 13 10 26 10)开头。

维基百科有一个用于识别文件的魔法数字列表,您可以查看它。只需创建一种方法来读取前几个字节并将其与该数字进行比较即可。


16

Rails的哪个版本?对于Rails 3,你应该查看添加的streaming方法。send_data是发送二进制数据的正确方式。如果图片是本地的并且你的web服务器支持它,你可以使用send_file,在用户下载图像时不会阻塞Rails实例。


3
是的,“send_data”是你想要的,不是“render”。 - aceofspades

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接