2009-10-10 3 views
37

Я пытаюсь загрузить изображение в PingFM. Их documentation говорит:Как закодировать носитель в базовом документе, указанном в Ruby

media – base64 encoded media data. 

Я могу открыть файл через URL. Я пробовал (практически угадали) это:

ActiveSupport::Base64.encode64(open("http://image.com/img.jpg")) 

Но я получаю эту ошибку:

TypeError: can't convert Tempfile into String 
    from /usr/lib/ruby/1.8/base64.rb:97:in `pack' 
    from /usr/lib/ruby/1.8/base64.rb:97:in `encode64' 
    from (irb):19 
    from :0 
+0

Я видел два ответа! Я не мог заставить работать khelll, потому что, как я подозреваю, я этого не понимал. Я выбираю mtyaka, потому что noobs, как я, могут легко это понять. Спасибо вам обоим! –

+1

Я знаю, что комментирую вопрос мертвого. Но когда вы работаете с базами данных, кодирующими base64, из базы данных, убедитесь, что она была дезинфицирована, или вы создаете инъекционное веб-приложение. – RobotHumans

ответ

44

open метод:

open("http://image.com/img.jpg") 

возвращает объект TempFile, в то время как encode64 ожидает строку.

Вызов read на TempFile должен сделать трюк:

ActiveSupport::Base64.encode64(open("http://image.com/img.jpg") { |io| io.read }) 
+0

Или .string также должен работать. – khelll

+5

Пожалуйста, не просто .read, он сохранит дескриптор файла открытым. В 1.9, и я думаю, что с помощью ActiveSupport вы можете открыть (url, &: read), который будет использовать форму блока и закрыть дескриптор файла при чтении. На ваниле 1.8, используйте open (url) {| io | io.read}. – manveru

+0

@manveru Право. Спасибо за комментарий - я обновил ответ. – mtyaka

10

закодировать файл в кодировке base64:

File.open("output_file","w"){|file| file.write [open("link_to_file").string].pack("m")} 

Декодирование base64 закодированный файл:

File.open('original', 'wb') {|file| file << (IO.readlines('output_file').to_s.unpack('m')).first } 
+0

в моем случае (ruby 2.0.0p481), 'open (" filename ").string' failed with * NoMethodError: undefined method 'string 'для # * – amenthes

18

Это тоже будет работать, это немного чище

require 'base64' 

Base64.encode64(open("file_path").to_a.join) 

«Как вы расшифровать это обратно в файл?» - @ user94154

require 'base64' 

open('output_file_name.txt', 'w') do |f| 
    f << Base64.decode64(encoded_content) 
end 

Где encoded_content бы ранее закодированный возвращаемое значение содержимого файла.

+0

Как вы декодируете это обратно в файл? – user94154

+1

@ user94154 Код добавлен в ответ. – robertodecurnex

+0

Этот ответ недействителен для более поздних версий Rails, поскольку он был удален после версии 3.2.13, как указано в [docs] (http://apidock.com/rails/ActiveSupport/Base64/encode64s/class). –

62

Для кодирования файла:

require 'base64' 
Base64.encode64(File.open("file_path", "rb").read) 

Для получения файла из закодированной строки:

require 'base64' 
encoded_string = Base64.encode64(File.open("file_path", "rb").read) 

File.open(file_name_to_create, "wb") do |file| 
    file.write(Base64.decode64(encoded_string)) 
end 
+0

rails 4.0.1 // фактически тот, который работает как ActiveSupport :: Base64 возвращает неинициализированную константу, даже изнутри приложения (консоли) rails – Ben

+4

Это должно быть верным ответом Работает без каких-либо драгоценных камней, непосредственно из ruby ​​irb. (Проверено на ruby ​​2.0.0-p481) – amenthes

+0

Работы. Без ActiveSupport. Для меня необходимо использовать «rb» в File.open. – Evmorov

1

Вот мое решение:

1: Поместите этот специальный метод IMAGE_TAG в ApplicationHelper, и включают модуль ActiveSupport

module ApplicationHelper 
    include ActiveSupport 
    def image_tag_base64(file_path, mime_type = 'image/jpeg', options = {}) 
    image_tag("data:#{mime_type};base64,#{Base64.encode64(open(file_path) { |io| io.read })}", options) 
    end 
end 

2: Затем, внутри зрения вы хотите использовать кодировку base64 изображение с помощью метода так:

<%= image_tag_base64 @model.paperclip_attribute.path(:size), @model.paperclip_attribute.content_type, {class: 'responsive-img etc etc'} %> 

3: СДЕЛАНО

Смежные вопросы