使用 ExifTool 从两个文件(一个原始文件,一个 XMP)读取
Reading from two files (one raw, one XMP) with ExifTool
我是 PERL 的新手,甚至是 ExifTool 的新手——因此我可能遗漏了一些非常基本的东西。
目标是从照片文件中读取 XMP 字段。查看 ExifTool 站点和 CPAN 上的 exiftool 文档,我能够读取标记的 jpeg 和 XMP sidecar 文件,两者都没有问题。
问题是当我从一个原始文件中读取时——显然没有自定义字段——我会收到一个带有未初始化值的错误。这是意料之中的事。
所以,我想要的代码是 "if you read a field/tag from the raw file and it isn't there, look at the associated XMP file, and if that fails, return a blank string."
因此我尝试打开 ExifTool 的第二个实例,例如:
my $exifInfo = ImageInfo($filePath);
转到
my $exifInfoXMP = ImageInfo($filePathXMP);
但这一直失败。如果我直接从 get-go 读取 XMP,它工作得很好,所以我得到的印象是我不能同时读取两个 ExifTool 结构(这不可能是对的;我必须是错误的这里)。下面的代码有效,但我不能 "interleave" 这两个文件的条件。我必须先处理原始文件,然后 运行 使用 XMP 的新处理程序进行第二次处理。知道 PERL 的效率如何,我的方法不可能是一个好的方法(即使它完成了工作)。
特别是有一行让我很疑惑。如果我删除它,则没有任何效果。 (一定要标好)
$filePath =~ s/$photoExtensions$/.XMP/i;
该行基本与从 get-go 读取 XMP 相同(不是我的理想解决方案)。
有人知道我哪里搞砸了吗?
谢谢,
保罗
header [已编辑以显示所有选项;已显示问题中使用的所有内容]
#!/usr/bin/perl
# load standard packages
use strict;
use warnings;
use Data::Dumper;
use File::Find;
no warnings 'File::Find';
use Image::ExifTool ':Public';
# define proxy for ExifTool
my $exifTool = new Image::ExifTool;
my $exifToolXMP = new Image::ExifTool;
# turn on immediate updates
$|=1;
# common extensions that I want to recognize
my $photoExtensions = "\.(jpg|crw|cr2|cr3|rw2|orf|raw|nef|arw|dng)";
my $imageExtensions = "\.(tiff|tif|psd|png|eps|hdr|exr|svg|gif|afphoto|pdf)";
my $videoExtensions = "\.(flv|vob|ogv|avi|mts|m2ts|mov|qt|wmv|mp4|m4p|m4v|svi|3gp|3g2)";
my $audioExtensions = "\.(aiff|aac|wav|mp3|m4a|m4p|ogg|wma)";
my $appFileExtensions = "\.(on1|cos|cof)";
my $GPSFileExtensions = "\.(gpx|kml|kmz|log)";
# start main program
main();
有问题的例程
sub listKeywords {
print "Reads and displays file information from certain tags (typically set in Photomechanic):\n";
print "\t1. Subject\n";
print "\t2. Hierarchical Subject\n";
print "\t3. Supplemental Categories\n";
print "\t4. Label Name 1\n";
print "\t5. Label Name 2\n";
print "\t6. Label Name 3\n";
print "\t7. Label Name 4\n\n";
print "List Keywords ---\n\tEnter file name (with path) --> ";
my $filePath = <STDIN>;
chomp $filePath;
$filePath =~ s/\//g;
$filePath =~ s/\s+$//;
########################################################
# COMMENT OUT THE FOLLOWING LINE AND NOTHING WORKS;
# $filePathXMP should be defined anyway, which suggests to
# me that the second invocation of ImageInfo doesn't actually occur.
# But I don't understand why.
$filePath =~ s/$photoExtensions$/.XMP/i;
print "\n\n";
my $filePathXMP = $filePath;
$filePathXMP =~ s/$photoExtensions$/.XMP/i; # TO FIX: filename may not have uppercase extension
# Get Exif information from image file
my $exifInfo = $exifTool->ImageInfo($filePath);
# my $exifInfoXMP = $exifToolXMP->ImageInfo($filePath =~ s/$photoExtensions$/.XMP/gi);
print "XMP Sidecar: \[$filePathXMP\]\n\n";
########################################################
# Get Specific Tag Value
my $hierarchicalSubject = $exifTool->GetValue('HierarchicalSubject');
my $subject = $exifTool->GetValue('Subject');
my $supplementalCategories = $exifTool->GetValue('SupplementalCategories');
my $labelName1 = $exifTool->GetValue('LabelName1');
my $labelName2 = $exifTool->GetValue('LabelName2');
my $labelName3 = $exifTool->GetValue('LabelName3');
my $labelName4 = $exifTool->GetValue('LabelName4');
my $exifInfo = ImageInfo($filePathXMP);
if (not defined $hierarchicalSubject) {$hierarchicalSubject = $exifTool->GetValue('HierarchicalSubject');}
if (not defined $hierarchicalSubject) {$hierarchicalSubject = "";}
if (not defined $subject) {$subject = $exifTool->GetValue('Subject');}
if (not defined $subject) {$subject = "";}
if (not defined $supplementalCategories) {$supplementalCategories = $exifTool->GetValue('SupplementalCategories');}
if (not defined $supplementalCategories) {$supplementalCategories = "";}
if (not defined $labelName1) {$labelName1 = $exifTool->GetValue('LabelName1');}
if (not defined $labelName1) {$labelName1 = "";}
if (not defined $labelName2) {$labelName2 = $exifTool->GetValue('LabelName2');}
if (not defined $labelName2) {$labelName2 = "";}
if (not defined $labelName3) {$labelName3 = $exifTool->GetValue('LabelName3');}
if (not defined $labelName3) {$labelName3 = "";}
if (not defined $labelName4) {$labelName4 = $exifTool->GetValue('LabelName4');}
if (not defined $labelName4) {$labelName4 = "";}
print "Subject:\n------------------------------\n$subject\n\n";
print "Hierarchical Subject:\n------------------------------\n$hierarchicalSubject\n\n";
print "Supplemental Categories:\n------------------------------\n$supplementalCategories\n\n";
print "Label Name 1:\n------------------------------\n$labelName1\n\n";
print "Label Name 2:\n------------------------------\n$labelName2\n\n";
print "Label Name 3:\n------------------------------\n$labelName3\n\n";
print "Label Name 4:\n------------------------------\n$labelName4\n\n";
}
由于你的代码不完整,我不得不问:你确定用以下几行开始你的脚本吗?
use strict;
use warnings;
这两行不是惹恼你的,它们会保护你免受你在代码中可能犯的简单错误的影响。
恕我直言,您 sub listKeywords()
的真正问题是以下行:
my $exifInfo = ImageInfo($filePathXMP);
这里有两个问题:
- 你重新定义了之前几行的变量
$exifInfo
。
- 您没有对第二个图像信息使用 OO 方法。
我想你打算写的是下面一行:
my $exifInfoXMP = $exifToolXMP->ImageInfo($filePathXMP);
我是 PERL 的新手,甚至是 ExifTool 的新手——因此我可能遗漏了一些非常基本的东西。
目标是从照片文件中读取 XMP 字段。查看 ExifTool 站点和 CPAN 上的 exiftool 文档,我能够读取标记的 jpeg 和 XMP sidecar 文件,两者都没有问题。
问题是当我从一个原始文件中读取时——显然没有自定义字段——我会收到一个带有未初始化值的错误。这是意料之中的事。
所以,我想要的代码是 "if you read a field/tag from the raw file and it isn't there, look at the associated XMP file, and if that fails, return a blank string."
因此我尝试打开 ExifTool 的第二个实例,例如:
my $exifInfo = ImageInfo($filePath);
转到
my $exifInfoXMP = ImageInfo($filePathXMP);
但这一直失败。如果我直接从 get-go 读取 XMP,它工作得很好,所以我得到的印象是我不能同时读取两个 ExifTool 结构(这不可能是对的;我必须是错误的这里)。下面的代码有效,但我不能 "interleave" 这两个文件的条件。我必须先处理原始文件,然后 运行 使用 XMP 的新处理程序进行第二次处理。知道 PERL 的效率如何,我的方法不可能是一个好的方法(即使它完成了工作)。
特别是有一行让我很疑惑。如果我删除它,则没有任何效果。 (一定要标好)
$filePath =~ s/$photoExtensions$/.XMP/i;
该行基本与从 get-go 读取 XMP 相同(不是我的理想解决方案)。
有人知道我哪里搞砸了吗?
谢谢,
保罗
header [已编辑以显示所有选项;已显示问题中使用的所有内容]
#!/usr/bin/perl
# load standard packages
use strict;
use warnings;
use Data::Dumper;
use File::Find;
no warnings 'File::Find';
use Image::ExifTool ':Public';
# define proxy for ExifTool
my $exifTool = new Image::ExifTool;
my $exifToolXMP = new Image::ExifTool;
# turn on immediate updates
$|=1;
# common extensions that I want to recognize
my $photoExtensions = "\.(jpg|crw|cr2|cr3|rw2|orf|raw|nef|arw|dng)";
my $imageExtensions = "\.(tiff|tif|psd|png|eps|hdr|exr|svg|gif|afphoto|pdf)";
my $videoExtensions = "\.(flv|vob|ogv|avi|mts|m2ts|mov|qt|wmv|mp4|m4p|m4v|svi|3gp|3g2)";
my $audioExtensions = "\.(aiff|aac|wav|mp3|m4a|m4p|ogg|wma)";
my $appFileExtensions = "\.(on1|cos|cof)";
my $GPSFileExtensions = "\.(gpx|kml|kmz|log)";
# start main program
main();
有问题的例程
sub listKeywords {
print "Reads and displays file information from certain tags (typically set in Photomechanic):\n";
print "\t1. Subject\n";
print "\t2. Hierarchical Subject\n";
print "\t3. Supplemental Categories\n";
print "\t4. Label Name 1\n";
print "\t5. Label Name 2\n";
print "\t6. Label Name 3\n";
print "\t7. Label Name 4\n\n";
print "List Keywords ---\n\tEnter file name (with path) --> ";
my $filePath = <STDIN>;
chomp $filePath;
$filePath =~ s/\//g;
$filePath =~ s/\s+$//;
########################################################
# COMMENT OUT THE FOLLOWING LINE AND NOTHING WORKS;
# $filePathXMP should be defined anyway, which suggests to
# me that the second invocation of ImageInfo doesn't actually occur.
# But I don't understand why.
$filePath =~ s/$photoExtensions$/.XMP/i;
print "\n\n";
my $filePathXMP = $filePath;
$filePathXMP =~ s/$photoExtensions$/.XMP/i; # TO FIX: filename may not have uppercase extension
# Get Exif information from image file
my $exifInfo = $exifTool->ImageInfo($filePath);
# my $exifInfoXMP = $exifToolXMP->ImageInfo($filePath =~ s/$photoExtensions$/.XMP/gi);
print "XMP Sidecar: \[$filePathXMP\]\n\n";
########################################################
# Get Specific Tag Value
my $hierarchicalSubject = $exifTool->GetValue('HierarchicalSubject');
my $subject = $exifTool->GetValue('Subject');
my $supplementalCategories = $exifTool->GetValue('SupplementalCategories');
my $labelName1 = $exifTool->GetValue('LabelName1');
my $labelName2 = $exifTool->GetValue('LabelName2');
my $labelName3 = $exifTool->GetValue('LabelName3');
my $labelName4 = $exifTool->GetValue('LabelName4');
my $exifInfo = ImageInfo($filePathXMP);
if (not defined $hierarchicalSubject) {$hierarchicalSubject = $exifTool->GetValue('HierarchicalSubject');}
if (not defined $hierarchicalSubject) {$hierarchicalSubject = "";}
if (not defined $subject) {$subject = $exifTool->GetValue('Subject');}
if (not defined $subject) {$subject = "";}
if (not defined $supplementalCategories) {$supplementalCategories = $exifTool->GetValue('SupplementalCategories');}
if (not defined $supplementalCategories) {$supplementalCategories = "";}
if (not defined $labelName1) {$labelName1 = $exifTool->GetValue('LabelName1');}
if (not defined $labelName1) {$labelName1 = "";}
if (not defined $labelName2) {$labelName2 = $exifTool->GetValue('LabelName2');}
if (not defined $labelName2) {$labelName2 = "";}
if (not defined $labelName3) {$labelName3 = $exifTool->GetValue('LabelName3');}
if (not defined $labelName3) {$labelName3 = "";}
if (not defined $labelName4) {$labelName4 = $exifTool->GetValue('LabelName4');}
if (not defined $labelName4) {$labelName4 = "";}
print "Subject:\n------------------------------\n$subject\n\n";
print "Hierarchical Subject:\n------------------------------\n$hierarchicalSubject\n\n";
print "Supplemental Categories:\n------------------------------\n$supplementalCategories\n\n";
print "Label Name 1:\n------------------------------\n$labelName1\n\n";
print "Label Name 2:\n------------------------------\n$labelName2\n\n";
print "Label Name 3:\n------------------------------\n$labelName3\n\n";
print "Label Name 4:\n------------------------------\n$labelName4\n\n";
}
由于你的代码不完整,我不得不问:你确定用以下几行开始你的脚本吗?
use strict;
use warnings;
这两行不是惹恼你的,它们会保护你免受你在代码中可能犯的简单错误的影响。
恕我直言,您 sub listKeywords()
的真正问题是以下行:
my $exifInfo = ImageInfo($filePathXMP);
这里有两个问题:
- 你重新定义了之前几行的变量
$exifInfo
。 - 您没有对第二个图像信息使用 OO 方法。
我想你打算写的是下面一行:
my $exifInfoXMP = $exifToolXMP->ImageInfo($filePathXMP);