渲染图像

Bin*_*gic 24 proxy ruby-on-rails image

所以这应该很简单,但我不能让它工作.

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

invalid byte sequence in UTF-8
Run Code Online (Sandbox Code Playgroud)

所以这就是我得到的.我希望有人能用我的代码解决问题或指导我更好的方向.

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
Run Code Online (Sandbox Code Playgroud)

远程文件工作正常,本地文件不工作.

任何可以帮助解决这个问题的人都可以获得奖励:

  1. 我需要设置正确的内容类型.远程图像网址不告诉我图像类型,我只是得到一个网址,有时网址不包含扩展名.所以我选择了jpeg,因为无论发送给我的图像类型如何,它似乎都有效.

谢谢!

Per*_*mal 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)开头.

维基百科有一个用于识别您可以查看的文件的幻数列表.只需创建一种读取前几个字节并将其与之比较的某种方法.


Zac*_*ker 14

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

  • 是的,`send_data` 是你想要的,而不是 `render`。 (3认同)