AIファイルからサムネールを取り出す試み【成功】 - なにする?DTP+WEB [d.hatena.ne.jp]
を、Perlでやってみた。
1.そのまま移植した。
Filename: thumbnail.pl
use strict;
use warnings;
use File::Basename;
use MIME::Base64;
if (-e $ARGV[0] ) {
my ( $fname, $dir, $ext ) = fileparse( $ARGV[0], qw(¥..*) );
open my $fh, '<', $ARGV[0] or die $!;
my $xmpmeta;
while ( <$fh> ) {
$xmpmeta .= $_;
last if m|</x:xmpmeta>|;
}
close $fh;
my $thumb = ( $xmpmeta =~ m|<xapGImg:image>(.+)</xapGImg:image>|sgo)[0];
( my $data = $thumb ) =~ s/
/¥n/sgo;
open my $fh2, '>', "$dir/$fname.jpeg" or die $!;
binmode $fh;
print $fh2 decode_base64( $data );
close $fh2;
}
exit;
__END__
2.ちゃんとパースした
AIファイルは、バージョン9以降はPDFになっているということで、PDF用パーサCAM::PDFを使いXMPメタデータを取得。
XMPメタデータは、XMLなので、XML用パーサXML::Simpleを使いデータを切り出し。
Filename: thumbnail2.pl
#!/usr/bin/perl
use strict;
use warnings;
use CAM::PDF;
use File::Basename;
use MIME::Base64;
use XML::Simple;
foreach ( @ARGV ) {
extract( $_ );
}
exit;
sub extract {
my $filename = shift;
return unless -e $filename;
my ( $fname, $dir, $ext ) = fileparse( $filename, qw(\..*) );
return unless my $xmpmeta = load_xmpmeta( $filename );
if ( my $data = parse_xml ( $xmpmeta ) ) {
open my $fh2, '>', "$dir/$fname.jpeg" or die $!;
binmode $fh2;
print $fh2 decode_thumbnail( $data );
close $fh2;
}
}
sub load_xmpmeta {
# CAM::PDFによるPDFパース
my $filename = shift;
my $pdf = CAM::PDF->new( $filename );
return unless my $objectnum = $pdf->getRootDict()->{Metadata}->{value};
my $xmpmeta = $pdf->getObjValue( $objectnum )->{StreamData}->{value};
return $xmpmeta;
}
sub parse_xml {
# XML::SimpleによるXMPパース
my $xml = shift;
my $xs = XML::Simple->new;
my $hash = $xs->XMLin( $xml );
my $data = $hash->{'rdf:RDF'}->{'rdf:Description'}
->[1]->{'xap:Thumbnails'}
->{'rdf:Alt'}->{'rdf:li'}->{'xapGImg:image'} or return;
return $data;
}
sub decode_thumbnail {
my $data = shift;
$data =~ s/
/\n/sgo;
return decode_base64( $data );
}
__END__
3.Image::ExifToolを使った。
CPANから、Image::ExifTool::XMPをインストールして、一発取得できるんですねー
Filename: thumbnail3.pl
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use Image::ExifTool;
foreach ( @ARGV ) {
extract( $_ );
}
exit;
sub extract {
my $filename = shift;
return unless -e $filename;
my ( $fname, $dir, $ext ) = fileparse( $filename, qw(\..*) );
my $exifTool = new Image::ExifTool;
$exifTool->ImageInfo( $filename, { Binary => 1, });
my $var = $exifTool->GetValue('ThumbnailImage');
return unless $var;
open my $fh, '>', "$dir/$fname.jpeg" or die $!;
binmode $fh;
print $fh $$var;
close $fh;
print "processed: $filename¥n";
}
__END__
〜〜〜
Perlの場合、ライブラリをインストールすると何でもできますね。逆にインストールの仕方を知らないと何もできないという。
(2009-5-17 14:27追記)
もっとも、Image::ExifTool入れちゃえば、コマンドラインツールが入るので
$ exiftool -b -ThumbnailImage test.ai > thumbnail.jpg
でできちゃうわけですけれども!