2009-07-21 3 views
40

Я интегрирую свое приложение Ruby on Rails с системой доставки usps. Как только вы делаете почтовый запрос, вы платите за эту почтовую рассылку, и она не возвращается.Как сохранить строку base64 как изображение с помощью ruby ​​

Почтовые запросы возвратят вам ответ 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 # put опасно и лучше всего избегать. Вы должны писать в двоичном режиме, что в основном не имеет отношения к платформам 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

1

Если вы нужно записать его на изображение, а затем использовать imagemagick через rmagick gem.

http://rmagick.rubyforge.org/

+3

как я могу это сделать? – juanpastas

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 (изображение: изображение) Сохранять 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