2013-02-17 52 views
1

目前,我正在撰写一个Sinatra应用程序,它可以从用户那里获取一些图片并返回一张新图片。RMagick&Sinatra:发送图片无需存储即可查看

有HAML形式的一部分:

%input{type:'file', name:'user_image'} 

而且有从处理程序代码:(蒙太奇是另一张照片)

source_userpic = params[:user_image][:tempfile] 
    blob = File.open(source_userpic).read 
    userpic = ImageList.new 
    userpic.from_blob(blob) 
    resized_img = userpic.scale(montage.columns, 
           montage.rows) 
    resized_img.opacity = MaxRGB/3 

然后两个图像是“分层”与复合材料和储存(唐需要)

final_picture = ImageList.new 
    final_picture << montage.composite(resized_img, 0, 0, OverCompositeOp) 


    final_picture.write("./public/uploads/#{DateTime.now}.jpg" # dirty (for example) 

接下来,我需要显示一个带有ajax的final_picture。有两个明显的问题:第一,我不需要保存final_picture - 这只是预览,第二,我必须编写代码以避免文件名冲突...

如何发送final_picture以查看? to_blob方法?但接下来呢?

回答

4

我通过使用数据URI方案解决了这个问题。

require 'base64' 

final_picture.format = "jpeg" # whatever 
# Using a to_blob method to create a direct-to-memory version of the image. 
# Then encode it to base64 string 
data_uri = Base64.encode64(final_picture.to_blob).gsub(/\n/, "") 
@image_tag = '<img alt="preview" src="data:image/jpeg;base64,%s">' % data_uri 

haml:'pages/preview' 

然后通过

= @image_tag 

不确定显示画面,如果它是最好的解决办法

+0

这不会避免文件名冲突,如果您获得具有相同名称的另一个文件并将其编码为64位,则会生成相同的输出。基数64是_encoding_,因此是**确定性**。 – iain 2013-02-19 23:37:26

+1

他没有用base64编码的名称创建文件,他在base64中编码图像内容,并使用接受该格式图像的html标记,因此完全避开了任何文件名问题。 – 2013-04-04 06:39:58

1

看看Tempfile,应该为您处理文件名冲突。

然后你可以使用the answers to this question的技术,使用send_file来发送tempfile。

您必须记住tempfile不会持续存在,因此如果您使用不同的请求和响应来提供文件,则必须小心地管理该持久性。

+0

谢谢回答!这在某些情况下可能会有帮助。 – user1201917 2013-02-18 11:37:32