2012-07-02 12 views
6

Ich verwende einen Dienst, um ein Bild an einen Server zu senden, und sie erfordern, dass das Bild vor dem Senden in das Base64-Format konvertiert wird. Ich habe versucht, MIME :: Base64 mit diesem Code:Perl Bild in Base64 konvertieren

use MIME::Base64(); 

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

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

und bekam diese Fehlermeldung

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

+1

Backslashes haben eine spezielle Bedeutung in doppelten Anführungszeichen. Sie möchten entweder einfache Anführungszeichen verwenden (''C: \ wamp \ www \ image.png''), die umgekehrten Schrägstriche mit mehr umgekehrten Schrägstrichen umgehen (' "C: \\ wamp \\ www \\ image.png" '), oder benutzen Sie einfach Schrägstriche (es ist OK, wirklich): '" C: /wamp/www/image.png "'. – mob

+0

Es scheint ein Problem mit Mime :: Base64-Modul unter Windows (zumindest mit ActiveState perl 5.8.8) - und ja, ich habe versucht, diese Subroutine mit 'Mime verwenden: Base64 qw (decode_base64)'. –

Antwort

10

Wenn Sie einen leeren Importliste angeben, wie folgt aus:

use MIME::Base64(); 

Sie bekomme keine Importe.

Änderung, die an die Leitung:

use MIME::Base64; 

Die () Pars angeben, dass MIME :: Base64 nichts zu Ihrem Namensraum exportiert. Das Standardverhalten (ohne die Parens) besteht darin, encode_base64 und decode_base64 zu exportieren. Sie überschreiben die bequeme Standardeinstellung. Wenn Sie wirklich main Namespace verschmutzen Ihr nicht diese Funktionen wünschen könnten Sie Ihre ursprüngliche use MIME::Base64() Linie behalten und dann Subroutinen-Aufruf vollständig qualifizieren:

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

Aber es ist sehr viel einfacher, und wahrscheinlich zufriedenstellend nur erlauben die Standard-Exportliste, die verarbeitet werden soll, indem die Klammer aus der Zeile use entfernt wird.

Aktualisieren Sie lesen auch nicht die Datei. Diese Zeile:

$base64_string = IMAGE; 

... sollte wie folgt aktualisiert werden:

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

Das Problem mehr verbosely erwischt worden wäre, wenn Sie use strict 'subs' in auswirkte. Das Problem ist, dass "IMAGE" an sich nur ein Barwort ist und Perl denkt, dass es ein Unterprogrammaufruf ist. Die spitzen Klammern, "<>" sind die übliche Art, von einem Dateihandle zu lesen. Der "local $/ = undef" Teil ist nur ein Mittel, um sicherzustellen, dass Sie die gesamte Datei schlürfen, nicht nur bis zur ersten Sequenz, die wie ein "\ n" für Perl aussieht.

Update2: Und wie MOB darauf hinweist, müssen Sie entweder die umgekehrten Schrägstriche auf Ihrem Weg umgehen oder Schrägstriche verwenden. Perl macht nichts, sogar auf Win32. Natürlich, da Sie den weisen Schritt der Verwendung von or die $! auf Ihrem open nehmen, haben Sie diesen Fehler bereits entdeckt.

+0

jetzt der entschlüsselte ist der Text "IMAGE" (brauche wirklich keine Decodierung, ich möchte nur ein Bild aus meinem Verzeichnis auswählen und zu Base 64 konvertieren) – Grigor

+0

Siehe mein Update in meiner ursprünglichen Antwort. – DavidO

+0

Bitte beachten Sie, dass Sie zumindest unter Windows 'binmode (filehandle)' verwenden müssen, da sonst die Base64-Ausgabe, die aus dem Binärdateiinhalt generiert wird, falsch ist (tatsächlich wurde eine Zip-Datei nach Base64 konvertiert) – elwood

0

Ein kurzes Base64 Encoder Programm:

# 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"; 

es mit dieser Befehlszeile verwenden:

perl to_base64.pl image_file.jpg 

Es schreibt eine Datei mit dem Namen image_file.jpg.b64 die Base64-codierte Eingabedatei enthält.

Base64 zu entschlüsseln, können Sie dieses Skript verwenden:

# 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"; 

Rufen sie diese Befehlszeile:

perl decode_base64.pl my_base64_file.b64 

Wenn der Dateiname als Parameter an diesem Skript mit .b64 endet versorgt diese Hinter 4 Zeichen werden entfernt: image_file.jpg.b64 =>image_file.jpg. Andernfalls fügt das Skript .bin dem Namen der Eingabedatei hinzu, um einen Ausgabedateinamen zu erhalten.