2012-07-02 12 views
6

Sto utilizzando un servizio per inviare un'immagine a un server e richiedono che l'immagine venga convertita in formato base64 prima di essere inviata. Ho provato MIME :: Base64 con questo codice:Perl converte l'immagine in base64

use MIME::Base64(); 

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

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

ed ho ottenuto questo messaggio di errore

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

+1

Le barre rovesciate hanno un significato speciale all'interno delle virgolette. O vuoi usare le virgolette singole (''C: \ wamp \ www \ image.png''), sfuggire alle barre inverse con più barre retroverse (' "C: \\ wamp \\ www \\ image.png" '), o usa solo le barre (va bene, davvero): '" C: /wamp/www/image.png "'. – mob

+0

Sembra esserci un problema con il modulo Mime :: Base64 su Windows (almeno con ActiveState perl 5.8.8) - e sì, ho provato ad importare quella subroutine con 'use Mime :: Base64 qw (decode_base64)'. –

risposta

10

Quando si specifica un elenco di importazione vuoto, in questo modo:

use MIME::Base64(); 

È non ottenere importazioni.

Change che la linea a:

use MIME::Base64; 

I () parentesi specifica che MIME :: Base64 esporta nulla a che lo spazio dei nomi. Il comportamento predefinito (senza parens) è di esportare encode_base64 e decode_base64. Stai ignorando il comodo valore predefinito. Se davvero non si vuole quelle funzioni inquinanti tua main spazio dei nomi si potrebbe conservare la linea originale use MIME::Base64(), e quindi completamente qualificare la chiamata subroutine:

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

Ma è molto più semplice, e probabilmente soddisfacente per solo consentire l'elenco di esportazione predefinito da elaborare rimuovendo la parentesi dalla riga use.

Aggiornamento Non stai leggendo il file. Questa linea:

$base64_string = IMAGE; 

... dovrebbe essere aggiornato in questo modo:

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

Questo problema sarebbe stato catturato più verbosely se si ha use strict 'subs' in effetti. Il problema è che "IMAGE" di per sé è solo una bareword, e Perl pensa che sia una chiamata di subroutine. Le parentesi angolari, "<>" sono il modo comune di leggere da un filehandle. La parte "local $/ = undef" è solo un modo per assicurare di far scorrere l'intero file, non solo fino alla prima sequenza che assomiglia a "\ n" a Perl.

Update2: E come indica MOB, è necessario che si stia sfuggendo alle barre rovesciate nel percorso o che si utilizzino le barre. Perl non importa, anche su Win32. Naturalmente dal momento che stai prendendo il passo da saggi usando or die $! sul tuo open, hai già scoperto questo errore.

+0

ora il decodificato è il testo "IMMAGINE" (non serve davvero alcuna decodifica, voglio solo selezionare un'immagine dalla mia directory e convertirla alla base 64) – Grigor

+0

Vedere il mio aggiornamento nella mia risposta originale. – DavidO

+0

Si noti che almeno su Windows è necessario utilizzare 'binmode (filehandle)', altrimenti l'output Base64 generato dai contenuti del file binario sarà errato (in realtà è stato osservato convertire un file zip in Base64) – elwood

0

Un breve programma Encoder 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"; 

utilizzarlo con questa riga di comando:

perl to_base64.pl image_file.jpg 

Scrive un file di nome image_file.jpg.b64 contenente il file di input con codifica Base64.

Per decodificare Base64, è possibile utilizzare questo 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"; 

chiamarlo utilizzando questa riga di comando:

perl decode_base64.pl my_base64_file.b64 

Se il nome del file fornito come parametro per lo script termina con .b64 questi trailing 4 i caratteri saranno rimossi: image_file.jpg.b64 =>image_file.jpg. In caso contrario, lo script aggiungerà .bin al nome del file di input per ottenere un nome file di output.