2009-07-21 147 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 
相關問題