渲染图像

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

我有一个控制器方法,基于查询查找图像,然后输出缓存。 图像可以是远程的(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. 我需要设置正确的内容类型。 远程图像url不告诉我图像类型,我只是得到一个url,有时url不包含扩展名。 所以我选择了jpeg,因为无论发送给我的图像类型如何,它似乎都能正常工作。

谢谢!

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

编辑

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

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

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