6

我正在使用一项服务将图片发送到服务器,他们要求在发送之前将图像转换为 base64 格式。我用以下代码尝试了 MIME::Base64:

use MIME::Base64 ();

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

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

并收到此错误消息

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

4

2 回答 2

14

当您指定一个空的导入列表时,如下所示:

use MIME::Base64 ();

你没有进口。这意味着函数名encode_base64不会被导入调用者的命名空间。您可以允许导入发生,也可以通过在调用它时显式引用它所在的包来完全限定函数名称。

要导入,将该行更改为:

use MIME::Base64;

()括号指定 MIME::Base64 不向您的命名空间导出任何内容。默认行为(没有括号)是导出encode_base64decode_base64. 通过在导入列表中使用空括号,您将覆盖导入这两个函数名称的方便默认行为。如果您真的不希望这些函数污染您的main命名空间,您可以保留原始use MIME::Base64 ()行,然后完全限定您的子例程调用:

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

但是通过从您的use行中删除括号来处理默认导出列表会容易得多,并且可能令人满意。

或者,您可以准确指定要导入的内容:

use MIME::Base64 ('encode_base64');

这将只导入encode_base64函数,但不会导入decode_base64,从而最大限度地减少命名空间污染。

更新您也没有阅读该文件。这一行:

$base64_string = IMAGE;

...应该像这样更新:

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

如果你有效果,这个问题会更详细地被发现use strict 'subs'。问题是 " IMAGE" 本身只是一个简单的词,Perl 认为它是一个子例程调用。尖括号“ <>”是从文件句柄中读取的常用方法。" local $/ = undef" 部分只是确保您对整个文件进行 slurp 的一种方式,而不仅仅是在第一个对 Perl 看起来像 "\n" 的序列之前。

Update2:正如 MOB 指出的那样,您要么需要转义路径中的反斜杠,要么使用正斜杠。Perl 不介意,即使在 Win32 上也是如此。当然,既然你是在你的 上使用的明智的一步or die $!open你已经发现了这个错误。

于 2012-07-02T22:14:09.897 回答
1

一个简短的 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";

将此命令行与它一起使用:

perl to_base64.pl image_file.jpg

它写入一个名为的文件image_file.jpg.b64,其中包含 Base64 编码的输入文件。

要解码 Base64,您可以使用以下脚本:

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

使用以下命令行调用它:

perl decode_base64.pl my_base64_file.b64

如果作为参数提供给此脚本的文件名以.b64这些尾随 4 个字符结尾,则将被删除:image_file.jpg.b64=> image_file.jpg。否则,脚本将添加.bin到输入文件名以获取输出文件名。

于 2017-02-07T16:30:40.003 回答