Как сохранить строку base64 как изображение, используя ruby - PullRequest
46 голосов
/ 21 июля 2009

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

Запросы на почтовые расходы вернут вам 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))
}

Ни одна из них не работает.

Ответы [ 4 ]

87 голосов
/ 21 июля 2009

При записи двоичных данных в файл, как, например, в случае с изображением, использование IO # put опасно и его лучше избегать. Вы должны писать в двоичном режиме, который в основном не имеет отношения к платформам только для LF, таким как UNIX или OS X, но обязателен для CRLF, таких как Windows. IO # put также добавляет в конец файла новую строку, которая является недействительной.

Наилучший подход - указать правильный флаг на открытом вызове:

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

17 голосов
/ 20 февраля 2016

Другие ответы довольно близки, но обычно предполагают, что поток 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
6 голосов
/ 11 декабря 2014
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 (image: image) # сохранить скрепку в фотомодели

1 голос
/ 21 июля 2009

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

http://rmagick.rubyforge.org/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...