2009-07-21 79 views
40

我正在将我的Ruby on Rails应用程序与usps送货系统集成。一旦您提出邮寄要求,您将为该邮资付款并且不可退款。如何使用ruby将base64字符串保存为图像

邮资请求将返回一个xml响应,其中包含一个base64字符串,它是运输标签。

我能够在视图中呈现运输标签,但为了使其万无一失,我希望能够将该base64字符串作为图像保存在我的服务器上,以防运输标签发生某种情况在代(支付它)和邮寄之间进行转换,因此可能不需要购买新的转载。

我的第一个想法是如下

# Attempt 1 
File.open('shipping_label.gif', 'w+') {|f| 
    f.puts Base64.decode64(base_64_encoded_data) 
} 

# Attempt 2 
File.open('shipping_label.gif', 'w+') {|f| 
    f.puts Base64.decode64(Base64.decode64(base_64_encoded_data)) 
} 

既不工作。

回答

77

在将二进制数据写入文件时(例如图像的情况),使用IO#puts会非常危险且最好避免。您应该使用二进制模式编写,这在大多数只有LF的平台(如UNIX或OS X)中是无关紧要的,但在CRLF(如Windows)上则势在必行。 IO#puts也会在文件末尾附加一个换行符,这是无效的。

最好的方法是指定正确的标志上公开征集:

File.open('shipping_label.gif', 'wb') do|f| 
    f.write(Base64.decode64(base_64_encoded_data)) 
end 

例如,看到IO#打开文档页面的意见:

http://apidock.com/ruby/IO/open/class

+1

这项工作非常完美。感谢您的解释和链接。 – Ricky 2009-07-21 19:55:46

3
require 'RMagick' 
data = params[:image_text]# code like this data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABPUAAAI9CAYAAABSTE0XAAAgAElEQVR4Xuy9SXPjytKm6ZwnUbNyHs7Jc7/VV9bW1WXWi9q 
image_data = Base64.decode64(data['data:image/png;base64,'.length .. -1]) 
new_file=File.new("somefilename.png", 'wb') 
new_file.write(image_data) 

你侃使用图像文件 Photo.new(图片:图片)后在照片模式#save useng回形针

10

其他的答案已经很接近,但通常认为的base64流将包含PNG数据。这并非总是如此,所以我建议使用MIME类型库来建立正确的文件扩展名:

REGEXP = /\Adata:([-\w]+\/[-\w\+\.]+)?;base64,(.*)/m 

data_uri_parts = data_url.match(REGEXP) || [] 
extension = MIME::Types[data_uri_parts[1]].first.preferred_extension 
file_name = "myfilename.#{extension}" 

File.open(file_name, 'wb') do |file| 
    file.write(Base64.decode64(data_uri_parts[2])) 
end 
相关问题