2009-10-10 19 views
37

Estoy intentando subir una imagen a PingFM. Su documentation dice:Cómo codificar medios en base64 URL dada en Ruby

media – base64 encoded media data. 

que pueden acceder a esta imagen a través de la URL. Probé (prácticamente adivinado) esto:

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

Pero me sale este error:

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

vi dos respuestas! No pude hacer que Khelll funcione porque, sospecho, no lo entendí demasiado. Estoy eligiendo mtyaka porque los noobs como yo podemos entenderlo fácilmente. ¡Gracias a ambos! –

+1

Sé que estoy comentando una pregunta irrelevante. Pero cuando maneja los datos de medios de codificación de base64 desde una base de datos, asegúrese de que se desinfectaron al entrar o crear una aplicación web inyectable. – RobotHumans

Respuesta

44

El open método:

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

está volviendo un objeto de archivo temporal, mientras que encode64 espera una cadena.

Calling read en el archivo temporal debe hacer el truco:

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

O .string debería funcionar también. – khelll

+5

Por favor, no solo leas, mantendrá abierto el descriptor de archivo. En 1.9, y creo que con ActiveSupport, puede abrir (url, &: leer), que utilizará el formulario de bloque y cerrará el identificador del archivo cuando termine de leer. En vanilla 1.8, use open (url) {| io | io.read} en su lugar. – manveru

+0

@manveru Derecha. Gracias por el comentario: actualicé la respuesta. – mtyaka

10

codificar un archivo de codificación base64:

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

base 64 Decodificar archivo codificado:

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

en mi caso (ruby 2.0.0p481), 'abrir (" nombre de archivo ").string' falla con * NoMethodError: método indefinido 'string 'para # * – amenthes

18

Esto funcionará también, que es un poco más limpio

require 'base64' 

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

"¿Cómo descodificar este de nuevo en un archivo?" - @ user94154

require 'base64' 

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

Dónde encoded_content sería el valor de retorno el contenido del archivo previamente codificada.

+0

¿Cómo decodifica esto en un archivo? – user94154

+1

@ user94154 El código ha sido agregado a la respuesta – robertodecurnex

+0

Esta respuesta no es válida para versiones posteriores de Rails, ya que se eliminó después de la versión 3.2.13 como se indica en [docs] (http://apidock.com/rails/ActiveSupport/Base64/encode64s/class). –

62

para codificar un archivo:

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

para producir el archivo de la cadena codificada:

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 // de hecho el que funciona como ActiveSupport :: Base64 devuelve una constante no inicializada, incluso desde dentro de una aplicación de rieles (consola) – Ben

+4

Esto debería ser de respuesta superior Funciona sin gemas, directamente de ruby ​​irb. (Probado en ruby ​​2.0.0-p481) – amenthes

+0

Obras. Sin ActiveSupport. Para mí es necesario usar 'rb' en File.open. – Evmorov

1

Aquí está mi solución:

1: Poner este método image_tag personalizado en ApplicationHelper, e incluye el módulo 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: A continuación, dentro de la vista que desea utilizar base64 imagen codificada utilizar el método como este:

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

3: HECHO