2009-10-10 6 views
37

Sto provando a caricare un'immagine su PingFM. La loro documentation dice:Come codificare i media nell'URL dato in base64 in Ruby

media – base64 encoded media data. 

posso accedere a questa immagine tramite l'URL. Ho provato (praticamente indovinato) questo:

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

Ma ottengo questo errore:

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

Ho visto due risposte! Non ero in grado di far funzionare Khelll perché, sospetto, non lo capivo molto. Sto raccogliendo i mtyaka perché i noob come me possono capirlo facilmente. Grazie a tutti e due! –

+1

So che sto commentando una domanda dead-ish. Ma quando ti occupi della codifica di base64 dei dati multimediali da un database, assicurati che sia sterilizzata o crei un'applicazione web iniettabile. – RobotHumans

risposta

44

open metodo:

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

restituisce un oggetto Temporanei, mentre encode64 prevede una stringa.

Calling read sul tempfile dovrebbe fare il trucco:

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

Oppure. dovrebbe funzionare anche. – khelll

+5

Si prega di non solo .read, manterrà aperto il descrittore di file. Su 1.9, e penso che con ActiveSupport, puoi aprire (url, &: read), che userà il modulo di blocco e chiuderà l'handle del file quando terminerà la lettura. Su vanilla 1.8, usa open (url) {| io | io.read} invece. – manveru

+0

@manveru Destra. Grazie per il commento - ho aggiornato la risposta. – mtyaka

10

codificare un file per la codifica Base64:

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

Base64 Decode file codificato:

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

nel mio caso (ruby 2.0.0p481), 'open (" nomefile ").string' fallisce con * NoMethodError: metodo non definito 'string 'per # * – amenthes

18

Ciò funzionerà anche, è un po 'più pulito

require 'base64' 

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

"Come fai a decodificare questo di nuovo in un file?" - @ user94154

require 'base64' 

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

Dove encoded_content sarebbe il valore di ritorno contenuti file precedentemente codificato.

+0

Come si decodifica questo in un file? – user94154

+1

@ user94154 Il codice è stato aggiunto alla risposta – robertodecurnex

+0

Questa risposta non è valida per le versioni successive di Rails come è stato rimosso dopo la versione 3.2.13 come indicato nella [docs] (http://apidock.com/rails/ActiveSupport/Base64/encode64s/class). –

62

per codificare un file:

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

Per produrre il file dalla stringa codificata:

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 // in realtà quello che funziona come ActiveSupport :: Base64 restituisce una costante non inizializzata, anche dall'interno di un'app per rotaie (console) – Ben

+4

Questa dovrebbe essere la migliore risposta Funziona senza gemme, direttamente da ruby ​​irb. (Testato su ruby ​​2.0.0-p481) – amenthes

+0

Funziona. Senza ActiveSupport. Per me è necessario usare 'rb' in File.open. – Evmorov

1

Ecco la mia soluzione:

1: Mettere questo metodo image_tag personalizzato in ApplicationHelper, e includere il modulo 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: Quindi, all'interno della vista che si desidera utilizzare base64 immagine codificata utilizzare il metodo come questo:

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

3: FATTO