在__DATA__句柄中存储二进制数据

时间:2015-03-10 00:24:18

标签: perl

在模块中,我需要一些图像数据(BMP)用于某些Imager::Search操作。以下作品,

my $pattern = Imager::Search::Pattern->new(
     driver => 'Imager::Search::Driver::BMP24',
     file   => 'test.bmp', #load the image from a file
);

图片test.bmp)对我来说是不变的,所以希望将其直接存储在源代码中

my $image = ... the image data ... ;

__DATA__部分。

test.bmp中存储二进制数据(例如__DATA__)的推荐方法是什么? (2.3kb的)。

2 个答案:

答案 0 :(得分:10)

您可能不想处理在源文件中存储原始二进制数据的麻烦,但这并不意味着您仍然无法使用存储图像的解决方案__DATA__段。__DATA__段。您只需先以纯文本格式对其进行编码,例如Base64。

Mojolicious就是这种事情的一个例子。使用Mojolicious::Lite,可以在use MIME::Base64; my $foo = do { local $/ = undef; decode_base64(<DATA>); }; print "<<$foo>>\n"; __DATA__ SnVzdCBhbm90aGVyClBlcmwgaGFja2VyLA== 部分的细分中嵌入模板和其他静态内容。如Mojolicious::Guides::Tutorial#Static Files中所述,Base64编码数据是一种可能性。

关键是要证明有时使用这种方法。如果您想实现使用此方法的解决方案,则可以使用核心Perl模块MIME::Base64。这是一个示例,其中一些任意普通旧文本以Base64格式存储,并检索以供使用。但是,由于Base64编码可用于二进制数据,因此可以调整此示例以存储图像。

{{1}}

答案 1 :(得分:3)

显然,@DavidO's answer是正确答案。您也可以使用十六进制而不是base64。

为此,首先将图像的十六进制转储附加到模块源文件。您可以执行此操作,例如,使用xxd

$ xxd -ps /path/to/image >> lib/My/Module.pm

假设您的模块文件以__DATA____END__结尾。

然后,您可以将十六进制转储转换回二进制。这当然是Perl,当然有各种各样的方式来做到这一点......并非所有方面都很好,包括以下内容:

sub load_data {
    my $bin;
    while (my $line = <DATA>) {
        $line =~ s/\s+\z//;
        $bin .= pack 'H*', $line;
    }
    $bin;
}

或者,如果你想啜饮:

my $png = pack 'H*',
          map { s{\s+}{}g; $_ }
          do { local $/; scalar <DATA> }
;
binmode STDOUT;
print $png;

当然,如果您的perl是5.14+,那么您可以利用s///r

my $png = pack 'H*', map s{\s+}{}gr, do { local $/; scalar <DATA> };

我的博文“Include image data in your Perl script or module”中提供了更多细节。

另请参阅perldoc packperldoc hex