渲染图像

时间:2011-02-27 21:36:51

标签: ruby-on-rails image proxy

所以这应该很简单,但我无法让它发挥作用。

我有一个基于查询查找图像的控制器方法,然后输出被缓存。图像可能是远程的(flickr,谷歌图像等),也可能是本地的。无论来源如何,我只需要获取图像文件内容,并将其传递给用户。从本质上讲,代理。通过远程图像似乎工作正常,但通过本地图像给我一个:

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. 我需要设置正确的内容类型。远程图像网址不告诉我图像类型,我只是得到一个网址,有时网址不包含扩展名。所以我选择了jpeg,因为无论发送给我的图像类型如何,它似乎都能正常工作。
  2. 谢谢!

2 个答案:

答案 0 :(得分: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)开头。

维基百科有list of magic numbers used to identify file你可以看一下。只需创建一种读取前几个字节并将其与之比较的某种方法。

答案 1 :(得分:14)

什么版本的Rails?对于Rails 3,您应该查看已添加的streaming methods。 send_data是发送二进制数据的正确方法。如果图像是本地的,并且您的Web服务器支持它,您可以使用send_file,它不会在用户下载图像时阻止rails实例。