2012-07-02 24 views
6

Estoy usando un servicio para enviar una imagen a un servidor y requieren que la imagen se convierta al formato base64 antes de que se envíe. Probé MIME :: Base64 con este código:Perl convertir la imagen a base64

use MIME::Base64(); 

open (IMAGE, "C:\\wamp\\www\\image.png") or die "$!"; 

$base64_string = IMAGE; 
$encoded = encode_base64($base64_string); 
print "Encode $encoded"; 

y tengo este mensaje de error

Undefined subroutine &mqin::encode_base64 called at line 6.

+1

Las barras diagonales inversas tienen un significado especial dentro de comillas dobles. Si desea utilizar comillas simples (''C: \ wamp \ www \ image.png''), escape las barras invertidas con más barras invertidas (' "C: \\ wamp \\ www \\ image.png" ', o simplemente use barras diagonales (está bien, realmente): '" C: /wamp/www/image.png "'. – mob

+0

Parece haber un problema con el módulo Mime :: Base64 en Windows (al menos con ActiveState perl 5.8.8) - y sí, he intentado importar esa subrutina con 'use Mime :: Base64 qw (decode_base64)'. –

Respuesta

10

Cuando se especifica una lista de importación vacío, así:

use MIME::Base64(); 

Usted no obtener importaciones

Cambio esa línea para:

use MIME::Base64; 

Los () parens se especifica que MIME :: Base64 exporta nada para el espacio de nombres. El comportamiento predeterminado (sin los parens) es exportar encode_base64 y decode_base64. Está anulando el conveniente predeterminado. Si realmente no quiere que esas funciones contaminar su main espacio de nombres que podría retener su línea original use MIME::Base64(), y luego totalmente a calibrar la llamada del subprograma:

$encoded = MIME::Base64::encode_base64($base64_string); 

Pero es mucho más fácil, y probablemente satisfactorio para simplemente permitir la lista de exportación predeterminada que se procesará eliminando el paréntesis de su línea use.

Actualización Tampoco está leyendo el archivo. Esta línea:

$base64_string = IMAGE; 

... debe actualizarse como esto:

$raw_string = do{ local $/ = undef; <IMAGE>; }; 
$encoded = encode_base64($raw_string); 

Ese problema habría sido capturado con más palabras si tuviera use strict 'subs' vigente. El problema es que "IMAGE" es solo una palabra, y Perl cree que es una llamada de subrutina. Los corchetes angulares, "<>", son la forma más común de leer desde una manejador de archivos. La parte "local $/ = undef" es solo un medio para asegurarse de que consume todo el archivo, no solo hasta la primera secuencia que se parece a "\ n" a Perl.

Update2: Y como señala MOB, o necesita escapar de las barras diagonales en su camino, o usar barras inclinadas. A Perl no le importa, incluso en Win32. Por supuesto, ya que está dando el sabio paso de usar or die $! en su open, ya ha descubierto este error.

+0

ahora el decodificado es el texto "IMAGEN" (realmente no necesita decodificación, solo quiero seleccionar una imagen de mi directorio y convertirla a la base 64) – Grigor

+0

Ver mi actualización en mi respuesta original. – DavidO

+0

Tenga en cuenta que al menos en Windows debe utilizar 'binmode (filehandle)', de lo contrario la salida de Base64 generada a partir del contenido del archivo binario será incorrecta (en realidad se observó la conversión de un archivo zip a Base64) – elwood

0

Un programa corto codificador Base64:

# to_base64.pl 
use MIME::Base64 qw(encode_base64); 

open (IMAGE, $ARGV[0]) || die "$!"; 
binmode(IMAGE); 
local $/; 
my $file_contents = <IMAGE>; 
close IMAGE; 
open (B64, ">$ARGV[0].b64") || die $!; 
print B64 encode_base64($file_contents); 
close B64; 
print "output file is $ARGV[0].b64\n"; 

lo uso con esta línea de comandos:

perl to_base64.pl image_file.jpg 

Se escribe un archivo llamado image_file.jpg.b64 que contiene el archivo de entrada codificada en Base64.

Para decodificar Base64, podría utilizar este script:

# decode_base64.pl 
use MIME::Base64 qw(decode_base64); 

open (B64, $ARGV[0]) || die "$!"; 
local $/; 
my $base64_string = <B64>; 
close B64; 
my $filename; 
if ($ARGV[0] =~ /.\.b64$/i) { 
    $filename = substr($ARGV[0], 0, length($ARGV[0]) - 4); 
} 
else { 
    $filename = "$ARGV[0].bin"; 
} 
open (IMAGE, ">$filename") || die $!; 
binmode(IMAGE); 
print IMAGE decode_base64($base64_string); 
close IMAGE; 
print "output file is $filename\n"; 

acceder a ella con esta línea de comandos:

perl decode_base64.pl my_base64_file.b64 

Si el nombre del archivo suministrado como parámetro para este script termina con .b64 éstos se arrastra 4 los caracteres serán eliminados: image_file.jpg.b64 =>image_file.jpg. De lo contrario, la secuencia de comandos agregará .bin al nombre del archivo de entrada para obtener un nombre de archivo de salida.