我该如何使用PerlMagick提取EXIF数据?

8

我目前正在使用Perl Magick http://www.imagemagick.org/script/perl-magick.php,这是Image Magick http://www.imagemagick.org的perl接口,用于处理和转换我们网站用户上传的照片。我希望能够捕获一些附加在这些图像上的EXIF数据,我已经能够通过使用以下命令来使用Image Magick的命令行界面完成此操作:

/usr/bin/identify -format "%[EXIF:*]" image.jpg

以下将返回特定照片的EXIF信息:

exif:ApertureValue=29/8
exif:ColorSpace=1
exif:CompressedBitsPerPixel=3/1
exif:CustomRendered=0
exif:DateTime=2002:10:08 19:49:52
exif:DateTimeDigitized=2002:09:29 14:03:55
exif:DateTimeOriginal=2002:09:29 14:03:55
exif:DigitalZoomRatio=1/1
exif:ExifImageLength=307
exif:ExifImageWidth=410
exif:ExifOffset=192
exif:ExifVersion=48, 50, 50, 48
exif:ExposureBiasValue=0/1
exif:ExposureMode=0
exif:ExposureTime=1/1000
exif:Flash=24
exif:FlashPixVersion=48, 49, 48, 48
exif:FNumber=7/2
exif:FocalLength=227/32
exif:FocalPlaneResolutionUnit=2
exif:FocalPlaneXResolution=235741/32
exif:FocalPlaneYResolution=286622/39
exif:Make=Canon
exif:MaxApertureValue=12742/4289
exif:MeteringMode=5
exif:Model=Canon PowerShot S30
exif:ResolutionUnit=2
exif:SceneCaptureType=0
exif:SensingMethod=2
exif:ShutterSpeedValue=319/32
exif:Software=Adobe Photoshop 7.0
exif:WhiteBalance=0
exif:XResolution=180/1
exif:YResolution=180/1

我已经尝试了大约100种方法来从Perl Magick获得相同的结果,但是无法弄清楚如何传递与命令行上使用的相同参数以使其正常工作。以下是我尝试过的一些变化,但似乎都没有起作用:

use Image::Magick;
my $image = Image::Magick->new;
my $exif = $image->Identify('image.jpg');
print $exif;

$image->Read('image.jpg');
$exif = $image->Get('format "%[EXIF:*]"');
print $exif;

我知道在Perl中从图像文件中提取EXIF数据的方法还有其他方式,但由于我们已经加载了Perl Magick模块,我不想浪费更多的内存来加载额外的模块。我希望有人已经在他们的网站上解决了这个问题,并能分享解决方案。非常感谢您的帮助!

3个回答

9
> cat im.pl
use Image::Magick;
my $image = Image::Magick->new();
$image->Read('/home/rjp/2009-02-18/DSC00343.JPG');
my $a = $image->Get('format', '%[EXIF:*]'); # two arguments
my @exif = split(/[\r\n]/, $a);
print join("\n", @exif);
> perl im.pl
exif:ColorSpace=1
exif:ComponentsConfiguration=...
exif:Compression=6
exif:CustomRendered=0
exif:DateTime=2009:02:13 16:18:15
exif:DateTimeDigitized=2009:02:13 16:18:15
...

看起来这个可以工作。

版本: ImageMagick 6.3.7 06/04/09 Q16 http://www.imagemagick.org


@rjp 谢谢!效果很棒,而且速度也超快。 - Russell C.
1
你是怎么想到的?这个API太晦涩难懂了! - rjh

2

我强烈推荐您使用Phil Harvey的ExifTool。它很全面且有良好的文档支持。此外,它不会将整个图像读入内存,并且根据文档,您只需向其传递打开图像文件的文件句柄即可从图像中获取Exif信息。因此,它不应浪费太多内存。


@Kinopiko - 如果我选择这条路线,你会建议我使用什么来调整用户上传的图像大小,而不是使用Perl Magick吗?我已经加载了Perl Magick和图像,以将原始上传的照片转换为多个不同大小的图像,供我们网站使用。我愿意尝试其他替代方案,但希望确保在使用更少的内存时,不会加载5个Perl模块并多次读取图像。谢谢! - Russell C.
哦,对不起,我误解了。我以为你指的是模块本身占用的内存,而不是多次加载图像。ExifTool在扫描图像时非常快,所以我怀疑它并不会将整个图像读入内存中。 - user181548
我查看了文档,似乎Exiftool甚至可以使用打开的文件句柄进行工作。我已经修改了答案以反映这一点。 - user181548

0

编辑:@rjp展示了如何访问所有信息而不是单个标签。以下是将数据放入哈希表中的方法:

#!/usr/bin/perl

use strict;
use warnings;

use Image::Magick;

my $image = Image::Magick->new;
$image->read('test.jpg');

my %exif = map { s/\s+\z//; $_ }
           map { split /=/, $_  }
           split /exif:/, $image->Get('format', '%[EXIF:*]');

use Data::Dumper;
print Dumper \%exif;

实际上你不需要。通过指定“EXIF:*”,您可以请求所有标签作为单个字符串。对我来说,这是更可取的,因为我可以轻松将所有EXIF标签的返回字符串转换为哈希表,从中可以使用任何我想要的标签。 - Russell C.
@Russel C. 是的,我知道。请注意我对@rjp帖子的投票和评论。 - Sinan Ünür

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接