2009-11-10 85 views
7

我目前使用Perl Magick http://www.imagemagick.org/script/perl-magick.php,图像Magick http://www.imagemagick.org的perl接口,来处理&转换我们网站用户上传的照片。我希望能够捕捉也有些附着在这些图片的EXIF数据中,我已经能够找出如何使用命令行界面难懂的做到这一点使用下面的命令:如何使用PerlMagick提取EXIF数据?

/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模块我不想通过加载额外的模块来浪费更多的内存。我希望有人在他们的网站上有这个工作,并可以分享解决方案。在此先感谢您的帮助!

回答

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 
... 

这似乎工作。

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

+0

+1现在,我为什么没有想到这一点。 – 2009-11-10 15:05:46

+0

@rjp谢谢!奇迹般有效。并且创纪录的时间。 – 2009-11-10 15:08:01

+1

你是怎么解决这个问题的?该API太钝了! – rjh 2013-02-10 22:20:22

1

我强烈建议你使用Phil Harvey的ExifTool。这是全面的和有据可查的。此外,它不会将整个图像读入内存,根据文档,只需将文件句柄传递给打开的图像文件即可从图像中获取Exif信息。所以它不应该浪费大量的内存。

+0

@Kinopiko - 如果我是走这条路,你会建议我用它来调整我们的用户上传的Perl Magick,而不是图像?我已经必须加载Perl Magick和图像,以将原始上传的照片转换为多种不同的尺寸以供我们的网站使用。我打开其他选择,但想确保我不会加载5个Perl模块,并在1或2个模块可以用更少的内存使用来实现这个技巧时多次读取图像。谢谢! – 2009-11-10 14:57:34

+0

哦,对不起,我误解了。我以为你的意思是模块本身所采用的内存,而不是多次加载图像。 ExifTool在扫描图像上非常快速,所以我怀疑它会将整个图像读入内存。 – 2009-11-10 15:01:49

+0

我检查了文档,看起来Exiftool甚至可以在打开的文件句柄下工作。我改变了答案来反映这一点。 – 2009-11-10 15:04:50

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; 
+0

其实你没有。您可以通过指定'EXIF:*'来请求所有标签为单个字符串。对我来说,这是更好的,因为我可以轻松地将所有EXIF标签的返回字符串转换为散列,我可以使用任何标签。 – 2009-11-10 15:30:56

+0

@Russel C.是的,我知道。请注意我的投票并对@ rjp的帖子发表评论。 – 2009-11-10 16:07:47