【问题标题】:How can I extract EXIF data using PerlMagick?如何使用 PerlMagick 提取 EXIF 数据?
【发布时间】:2009-11-10 14:36:53
【问题描述】:

我目前正在使用 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 模块,我不想因为必须加载额外的模块而浪费更多内存。我希望有人已经在他们的网站上进行了这项工作,并且可以分享解决方案。提前感谢您的帮助!

【问题讨论】:

    标签: perl imagemagick exif


    【解决方案1】:
    > 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 谢谢!奇迹般有效。而且在创纪录的时间内。
    • 你是怎么想出来的? API 太迟钝了!
    【解决方案2】:

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

    【讨论】:

    • @Kinopiko - 如果我要走那条路,你会建议我用什么来调整用户上传的图像而不是 Perl Magick?我已经加载了 Perl Magick 和图像,以将上传的原始照片转换为多种不同尺寸,以便在我们的网站上使用。我对其他替代方案持开放态度,但想确保我没有加载 5 个 perl 模块并多次读取图像,而 1 或 2 个模块可以用更少的内存使用来完成这个技巧。谢谢!
    • 哦,对不起,我误会了。我以为您的意思是模块本身占用的内存,而不是图像的多次加载。 ExifTool 扫描图像的速度非常快,所以我怀疑它会将整个图像读入内存。
    • 我检查了文档,看起来 Exiftool 可以使用打开的文件句柄。我已更改答案以反映这一点。
    【解决方案3】:

    编辑: @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 标记的返回字符串转换为一个哈希值,我可以从中使用任何我想要的标记。
    • @Russel C. 是的,我知道。请注意我对@rjp 帖子的投票和评论。
    猜你喜欢
    • 2015-01-19
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 2012-04-21
    • 2014-08-13
    • 1970-01-01
    • 2019-06-13
    • 2014-12-26
    相关资源
    最近更新 更多