Fundamental problem calling Exiftool ImageInfo from within a Perl program

Started by Archive, May 12, 2010, 08:53:50 AM

Previous topic - Next topic

Archive

[Originally posted by stevebright on 2005-07-11 21:50:15-07]

I'm trying to write a fairly basic program that will scan a directory tree and access the Exif information for all image files it finds. Then it will rename the image file, store some details somewhere and maybe move the file too. The problem is, I'm having a lot of trouble calling the ImageInfo function, particularly from within a function. I suspect there is a fairly basic flaw in my Perl, but one of my colleagues who has a lot more experience with Perl can't spot the problem either.

Here's a summary of my directory structure:

Code:
C:\exifstuff
C:\exifstuff\lib
C:\exifstuff\lib\File
C:\exifstuff\lib\File\RandomAccess.pm
C:\exifstuff\lib\Image\ExifTool.pm
C:\exifstuff\lib\Image\ExifTool\ ...
C:\exifstuff\stevesimages
C:\exifstuff\stevesimages\19902_20D_A.JPG
The following code works. It traverses the directories starting at C:\exifstuff\stevesimages, correctly printing out the JPG file it finds and, just to prove that it works, calls ImageInfo directly on the file after the traversal is over.

Code:
use Image::ExifTool 'ImageInfo';
use File::Find;

find( \&traverse, "C:/exifstuff/stevesimages" );

$info = ImageInfo( "C:/exifstuff/stevesimages/19902_20D_A.JPG", "DateTimeOriginal" );
print $info->{DateTimeOriginal} . "\n";

sub traverse {
    if (/\.JPG$/) {
        print $File::Find::dir . "," . $_ . "\n";
    }        
}
It's in a file called z1.pl, my current directory is set to C:\exifstuff, and I run it with the command perl -Ilib z1.pl

If I move the ImageInfo call to within the traverse function, i.e. where it's supposed to go, I get an error, and that's without changing anything else, like actually giving it the name of image file found instead of the hard-coded one.

Code:
use Image::ExifTool 'ImageInfo';
use File::Find;

find( \&traverse, "C:/exifstuff/stevesimages" );

sub traverse {
    if (/\.JPG$/) {
        print $File::Find::dir . "," . $_ . "\n";
        $info = ImageInfo( "C:/exifstuff/stevesimages/19902_20D_A.JPG", "DateTimeOriginal" );
        print $info->{DateTimeOriginal} . "\n";

    }        
}
This is in file z2.pl and it's run with the command perl -Ilib z2.pl. The error I get is:

Can't locate Image/ExifTool/Exif.pm in @INC (@INC contains: lib C:/Perl/lib C:/Perl/site/lib .) at (eval 5) line 3.

Can't find table Image::ExifTool::Exif::Main

Can't locate Image/ExifTool/Shortcuts.pm in @INC (@INC contains: lib C:/Perl/lib C:/Perl/site/lib .) at lib/Image/ExifTool.pm line 1240.

I'd really appreciate some guidance on this. I feel quite sure there must be a fairly simple solution, but I don't know what it is! Details: Windows XP, Perl v5.8.7 built for MSWin32-x86-multi-thread, ExifTool v5.30.

Oh, if possible I'd like to stick to non-object-oriented use as my brain is nearly full!

Thanks in advance, Steve

Archive

[Originally posted by exiftool on 2005-07-12 12:04:08-07]

Hi Steve,

The problem is that Perl can't find the necessary libraries.  You can solve this problem in two ways:

1) install exiftool so the libraries are in the standard location (read the instructions in the README).

2) if the exiftool 'lib' directory is in the same directory as your main script, you can use the following code in your script to set things up properly (from the 'exiftool' script):

Code:
#!/usr/bin/perl -w
use strict;
require Image::ExifTool;  #note:  do not use 'use'
import Image::ExifTool 'ImageInfo';

my $exeDir;
BEGIN {
    # get exe directory
    $exeDir = $0;           # get exe directory from command
    $exeDir =~ tr/\\/\//;   # for systems that use backslashes
    # isolate directory specification
    $exeDir =~ s/(.*)\/.*/$1/ or $exeDir = '.';
    # add lib directory at start of include path
    unshift @INC, "$exeDir/lib";
}

# ...

Archive

[Originally posted by stevebright on 2005-07-12 22:54:08-07]

Thanks very much for your help. I tried method #2, but it didn't seem to make any difference. I then tried to follow the installation instructions from the README file, but found that I don't have 'make'. However, I copied the File and Exiftool directories into my C:\perl\site\lib directory and it now works. So I am very relieved and can actually start cutting some code. I am still a bit mystified as to why the ImageInfo call worked outside the function, but not inside. Thanks again, Steve.

Archive

[Originally posted by exiftool on 2005-07-13 11:28:33-07]

The reason that the call worked outside the function but not inside is because Perl was finding the ExifTool libraries via a relative path entry in your @INC ('lib').  If you change the current directory, then the relative path no longer works (ie. to a directory that doesn't contain 'lib'), and apparently Find() is changing the current directory.