Convert Canon zb4meta.info to xmp?

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

Previous topic - Next topic

Archive

[Originally posted by jpf961 on 2006-12-19 15:30:42-08]

I have about 5 years worth of photos with associated keywords archived in Canon's ZoomBrowserEX. The keywords are in XML, and are maintained by folder in the zb4meta.info file. I'd like to rip each of the .info files and embed the keywords in XMP format within the appropriate JPEG image.

Has anyone done this before? If so, could you provide scripts or information on how to use ExifTool's command line to do this?

FYI, each photo entry in the zb4meta.info file is in the following XML format:

<item:foo123.jpg>

<kwd_people>"George"</kwd_people>

<kwd_place>"Paris"</kwd_place>

<kwd_event>"Vacation"</kwd_event>

(Phil, thanks for everything that you've put into this!)

Archive

[Originally posted by exiftool on 2006-12-19 15:53:47-08]

This sounds like a fairly easy script to work up.  I could do this
if you provide me with a full complete zb4meta.info file to play
with.  You can send it to philharvey66 at gmail.com.

- Phil

Archive

[Originally posted by exiftool on 2006-12-19 18:29:41-08]

I got the file, thanks.  Good thing too, it is encoded in unicode,
and that needed to be handed by the script.

So here is a script you can start with.  You will want to define your mappings
in the %map hash to write the tags that best suite your needs (I have only
scratched in some possibilities here).  As always, be sure you have backups
before you start editing any images (with this script, or otherwise):

Code:
#!/usr/bin/perl -w
#
# File:     zb4meta_conv
#
# Syntax:   zb4meta_conv <ZB4 meta file> [<image directory>]
#
use strict;
BEGIN {
    # get exe directory
    my $exeDir = ($0 =~ /(.*)[\\\/]/) ? $1 : '.';
    # add lib directory at start of include path
    unshift @INC, "$exeDir/lib";
}
use Image::ExifTool;

# mapping for ZB4 information to XMP
my %map = (
    kwd_place       => 'XMP:Location',
    kwd_people      => 'XMP-dc:Subject',
    kwd_event       => 'XMP-dc:Description',
    kwd_others      => 'XMP-tiff:UserComment',
    Favourite_Photo => 'XMP:Rating',
);

my $infoFile = shift;
my $imageDir = shift || '';

die "SYNTAX: zb4meta_conv <ZB4 meta file> [<image directory>]\n" unless $infoFile;

$imageDir .= '/' if $imageDir;

my $size = -s $infoFile or die "Error getting size of $infoFile\n";
open FILE, $infoFile or die "Error opening $infoFile\n";
binmode FILE;

my $buff;
read(FILE, $buff, $size) or die "Error reading file\n";
close FILE;

# convert from unicode to characters
$buff = pack('C0U*',unpack("v*",$buff));

my $exifTool = new Image::ExifTool;

# loop through items
my $count = 0;
while ($buff =~ m{\G.*?<item:(.*?)>(.*?)</item:\1>}sg) {
    $exifTool->SetNewValue();   # reset old values
    my ($image, $meta) = ($1, $2);
    print "==== Processing $image\n";
    # unpack information
    while ($meta =~ m{\G.*?<(.*?)>(.*?)</\1>}sg) {
        my ($tag, $val) = ($1, $2);
        $val =~ s/^("?)(.*)\1$/$2/; # remove quotes
        my $newTag = $map{$tag} || '';
        print "$tag = $val [$newTag]\n";
        next unless $newTag;
        $exifTool->SetNewValue($newTag, $val);
    }
    my $file = "$imageDir$image";
    if (-e $file) {
        my $val = $exifTool->WriteInfo($file);
        if (not $val) {
            print "ERROR writing $file\n";
        } elsif ($val == 1) {
            print "Updated $file\n";
            ++$count;
        } else {
            print "No changes made to $file\n";
        }
    } else {
        print "File doesn't exist: $file\n";
    }
}

print "====\n$count files changed\n";

# end

- Phil