Checking for TAG in pair of files

Started by msbc, January 16, 2017, 12:38:50 AM

Previous topic - Next topic

Hayo Baan

Sorry it took a while but I have come up with a solution that works in all cases now. You can now provide either a non-xmp file or an xmp file and it will work if the gps is set.

  • For non-xmp files it will try to see if gps is set in itself or in the matching xmp
  • For xmp files it will look for all files that match the xmp file (i.e. all files that match base.* where base is the name of the xmp file without the xmp suffix)
I also changed the return value, instead of a number, it will now return the name of the file in which the gps data was found (still allowing the -if trick).

The toughest trick was actually to prevent internal looping of the metadata extraction calls (looking for the metadata in a mov file would trigger looking for the data in the xmp which would also look into the mov which would then look into the xmp, etc.). I fixed this by no longer extracting composite tags for the secondary files (which is also going to slightly faster). I therefore needed to also look for the GPSCoordinates tag instead of just the GPSLatitude tag as e.g. quicktime movies store the info there.

Here's the new code:
#!/usr/bin/perl

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        GPSIsSet => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
            },
            Desire => {
                2 => 'GPSLatitude',
                3 => 'GPSCoordinates',
            },
            RawConv => q{
                require File::Spec;
                my $file = File::Spec->catfile($val[0], $val[1]);
                return $file if defined $val[2] or defined $val[3];
                my $base = File::Spec->catfile($val[0], $val[1]);
                $base =~ s/\.[^.]+$//;
                my @files = grep { ($val[1] =~ /\.xmp$/i) ^ /\.xmp$/i } glob(qq("$base.*"));
                for my $file (@files) {
                    if (-f $file) {
                        my $et = Image::ExifTool->new;
                        $et->ExtractInfo($file, { Composite => 0, Duplicates => 0 });
                        return $file if defined $et->GetValue('GPSLatitude') or defined $et->GetValue('GPSCoordinates');
                    }
                }
                return '';
            },
        },
    },
);

1;
Hayo Baan – Photography
Web: www.hayobaan.nl

Phil Harvey

...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Hayo Baan

Quote from: Phil Harvey on January 19, 2017, 06:29:56 AM
Very smart.
;D
Actually I noticed it can be done slightly shorter even (without the extra $base variable that I needed in a different approach to prevent the file loading-loop):
#!/usr/bin/perl

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        GPSIsSet => {
            Require => {
                0 => 'Directory',
                1 => 'FileName',
            },
            Desire => {
                2 => 'GPSLatitude',
                3 => 'GPSCoordinates',
            },
            RawConv => q{
                require File::Spec;
                my $file = File::Spec->catfile($val[0], $val[1]);
                return $file if defined $val[2] or defined $val[3];
                $file =~ s/\.[^.]+$//;
                my @files = grep { ($val[1] =~ /\.xmp$/i) ^ /\.xmp$/i } glob(qq("$file.*"));
                for my $file (@files) {
                    if (-f $file) {
                        my $et = Image::ExifTool->new;
                        $et->ExtractInfo($file, { Composite => 0, Duplicates => 0 });
                        return $file if defined $et->GetValue('GPSLatitude') or defined $et->GetValue('GPSCoordinates');
                    }
                }
                return '';
            },
        },
    },
);

1;

(I left the single use of @files in as that improves readability)
Hayo Baan – Photography
Web: www.hayobaan.nl

msbc

Hayo,

Is GPSCoordinates a composite tag you defined? It's not in my NEFs.

I'm going to optimise your code for my use-case, i'll post a version back here when I can.

Thanks,
Mark
- Mark

Hayo Baan

Quote from: msbc on January 20, 2017, 02:02:41 AM
Is GPSCoordinates a composite tag you defined? It's not in my NEFs.
No, it's the tag that gets the gps info in movie files (at least when from an iPhone, but perhaps also from a Nikon camera with gps module). To allow for this, I added the tag.

Quote from: msbc on January 20, 2017, 02:02:41 AM
I'm going to optimise your code for my use-case, i'll post a version back here when I can.
OK! (Though not testing for the additional tag is probably not that costly)
Hayo Baan – Photography
Web: www.hayobaan.nl