News:

2023-03-15 Major improvements to the new Geolocation feature

Main Menu

Picasa.ini to XMP-mwg-rs/XMP-MP Region tags

Started by StarGeek, March 03, 2015, 05:16:54 PM

Previous topic - Next topic

StarGeek

I'm currently trying to make User-Defined tags that will read the .picasa.ini file that might be in the same directory as target file and check to see if there are any facial recognition regions for the target file.  If so, it will create the  XMP-mwg-rs (Media Work Group/Picasa) and XMP-MP (Microsoft Photo) Region tags so they can be inserted directly into a file without having to use some other program.

I seem to have most of it correct, as the numbers are coming out nearly the same as when I use AvPicFaceXmpTagger, at worst it's only 0.0000001 off.  But I seem to have messed up the returning of data from the tag.  When I add -struct, it returns data which matches the XMP-mwg-rs and XMP-MP data already in my file.  But without that option, I get output similar to this:
Picasa Ini To MWG Region        : HASH(0x3268b74)
Picasa Ini To MP Region         : HASH(0x3268934)

while the conversion tags from this thread (which this is heavily based upon) won't show any info without the -struct option.

Hopefully, there's just a simple mistake that's due to my lack of knowledge about Perl.  Any chance you can take a look at this Phil?

%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
PicasaIniToMWGRegion => {
Require =>
{
0 => 'Directory',
1 => 'FileName',
2 => 'ImageWidth',
3 => 'ImageHeight',
},
ValueConv => q{
my ( %ImageReg, $Filename , $PicasaIni, $section, %ContactHash, @RegList);
my $DoneFlag = 0;
$PicasaIni= "$val[0]/.picasa.ini";
$Filename = $val[1];
$ContactHash{'ffffffffffffffff'}='ffffffffffffffff'; #Picasa's default setting for unnamed faces.
open (INI, $PicasaIni) || return undef;
while ( ($_=<INI>) && !$DoneFlag) {
chomp;
if (/^\s*\[(.+)\](?:$)/) {
$section = $1;
}
# First Section should be the contact list.  Put that into a hash so we can pull the names out later
if ($section eq 'Contacts2')
{
if (/^([\da-f]{1,16})=(.*);;$/) 
{
my $keyword = $1;
my $value = $2 ;
# put them into hash
$ContactHash{$keyword} = $value;
}
}
# After the contact list, the following sections are all the filenames if they have
elsif ($section eq $Filename)
{
$DoneFlag=1;
$_=<INI>;
chomp;
if (/^faces=(.*)$/)  #(?:rect64\([\da-f]{12,16}\),[\da-f]{14,16};?)+
{
my @temp = split(/;/,$1);
foreach (@temp)
{
/rect64\(([\da-f]{12,16})\),([\da-f]{14,16})/;
my $contact=$2;
my $left  = substr ($1,0,-8);
my $right = substr ($1,-8);
# using 7 as arbitrary.  I've seen lengths vary from 6 to 8
my @rec;
$rec[0] = sprintf("%.7f",((hex($left) & 0xFFFF0000)>>16)/65535);
$rec[1] = sprintf("%.7f",(hex($left) & 0xffff)/65535);
$rec[2] = sprintf("%.7f",((hex($right) & 0xFFFF0000)>>16)/65535);
$rec[3] = sprintf("%.7f",(hex($right) & 0xFFFF)/65535);
%ImageReg=(
Area =>
{
X => $rec[0]+($rec[2]-$rec[0])/2,
Y => $rec[1]+($rec[3]-$rec[1])/2,
W => $rec[2]-$rec[0],
H => $rec[3]-$rec[1],
Unit => 'normalized',
},
Name => $ContactHash{$contact},
Type => 'Face',
);
push @RegList, \%ImageReg;
}
}
}
}
close (INI);
return
{
AppliedToDimensions => { W => $val[2], H => $val[3], Unit => 'pixel' },
RegionList => \@RegList,
}
},
},
PicasaIniToMPRegion =>
{
Require =>
{
0 => 'Directory',
1 => 'FileName',
},
ValueConv => q{
my ($Filename , $PicasaIni, $section, %ContactHash, @RegList);
my $DoneFlag = 0;
$PicasaIni= "$val[0]/.picasa.ini";
$Filename = $val[1];
$ContactHash{'ffffffffffffffff'}='ffffffffffffffff'; #Picasa's default setting for unnamed faces.
open (INI, $PicasaIni) || return undef;
while ( ($_=<INI>) && !$DoneFlag) {
chomp;
if (/^\s*\[(.+)\](?:$)/) {
$section = $1;
}
# First Section should be the contact list.  Put that into a hash so we can pull the names out later
if ($section eq 'Contacts2')
{
if (/^([\da-f]{1,16})=(.*);;$/) 
{
my $keyword = $1;
my $value = $2 ;
# put them into hash
$ContactHash{$keyword} = $value;
}
}
# After the contact list, the following sections are all the filenames if they have
elsif ($section eq $Filename)
{
$DoneFlag=1;
$_=<INI>;
chomp;
if (/^faces=(.*)$/) 
{
my @FaceRegions = split(/;/,$1);
foreach (@FaceRegions)
{
/rect64\(([\da-f]{12,16})\),([\da-f]{14,16})/;
my $contact=$2;
my $left  = substr ($1,0,-8);
my $right = substr ($1,-8);
# using 7 as arbitrary precision.  I've seen lengths vary from 6 to 8
my @rec;
$rec[0] = sprintf("%.7f",((hex($left) & 0xFFFF0000)>>16)/65535);
$rec[1] = sprintf("%.7f",(hex($left) & 0xffff)/65535);
$rec[2] = sprintf("%.7f",((hex($right) & 0xFFFF0000)>>16)/65535) - $rec[0];
$rec[3] = sprintf("%.7f",(hex($right) & 0xFFFF)/65535) - $rec[1];


push @RegList,
{
PersonDisplayName => $ContactHash{$contact},
Rectangle => join(', ', @rec),
};
}
}
}
}
close (INI);
return { Regions => \@RegList };
},
},
},
);
#------------------------------------------------------------------------------
1;  #end


edit: better alignment
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Wow, that's very interesting.  Creating a user-defined Composite Struct tag when there is no -struct option in effect.

You aren't doing anything wrong Perl-wise.  The problem is that ExifTool has no mechanism to generate flattened tags from a user-defined Struct tag.  Thinking a bit about this, I don't even know how I would go about adding this ability.

But do you really need this?  Perhaps it would be sufficient to just return the serialized structure without the -struct option, like this:

my $struct = {
AppliedToDimensions => { W => $val[2], H => $val[3], Unit => 'pixel' },
RegionList => \@RegList,
};
unless ($self->Options('Struct')) {
require 'Image/ExifTool/XMPStruct.pl';
$struct = Image::ExifTool::XMP::SerializeStruct($struct);
}
return $struct;


Note that the MyRegion tag in the thread you referenced is never extracted without the -struct option, so you aren't exposed to the underlying HASH as you are in your case.  An alternative is to just return undef unless the Struct option is set.  I'm not really sure if somehow generating flattened Composite tags is an alternative.

- Phil
...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 ($).

StarGeek

Quote from: Phil Harvey on March 03, 2015, 07:31:42 PMThe problem is that ExifTool has no mechanism to generate flattened tags from a user-defined Struct tag.  Thinking a bit about this, I don't even know how I would go about adding this ability.

Sorry if I'm not making myself clear.  I don't need flattened tags.  I want to create a tag that will create tags from the picasa.ini that I can insert into -RegionInfo and -RegionInfoMP.  So I'm looking for something like this as the end command:

exiftool -config PicasaIniConvert  "-regioninfo<PicasaIniToMWGRegion" "-regioninfomp<PicasaIniToMPRegion" FILE/DIR

To be honest, I don't quite understand the -struct option, but I'm certainly willing to use if it's what is needed to get this idea to work.  I've tried adding it at various times in my testing, but never with any results.

* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

Hold on, I think I was making a stupid mistake and I was not using the right config file.  I think it's working :D

Yep, it looks like a stupid mistake on my end.  I may be getting hash when I treat it as a flatten tag, but when I try to copy it, it appears to be working.  I need to do some more testing, then tweak the code a bit, then try and add in the bit from the other thread but test for a change in directory, but now it's looking good.

Thanks for the feedback.  I'm sure I'll have a few more questions later.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

#4
Right.  It should be fine to copy this tag to the appropriate structured tag.  The problem is only if you try to display it when extracting.

This is exciting because there have been a few requests for this ability.  If you come up with something that other people can use, perhaps I can add it to the ExifTool distribution.

- Phil

Edit:  To keep from re-loading the INI file each time, you could define this in your config file:

$Image::ExifTool::myIniFile = '';
@Image::ExifTool::myIniData = ();

sub Image::ExifTool::LoadINI($)
{
    my $iniFile = shift;
    if ($iniFile eq $Image::ExifTool::myIniFile) {
        return undef unless @Image::ExifTool::myIniData;
    } else {
        $Image::ExifTool::myIniFile = $iniFile;
        undef @Image::ExifTool::myIniData;
        local *INI;
        open(INI, $iniFile) or return undef;
        while (<INI>) {
            chomp;
            push @Image::ExifTool::myIniData, $_;
        }
        close(INI);
        @Image::ExifTool::myIniData or return undef;
    }
    return 1;
}


Then the first statement in your ValueConv could be "LoadINI("$val[0]/.picasa.ini") or return undef;", and you would parse @Image::ExifTool::myIniData in your loop:

foreach (@Image::ExifTool::myIniData) {
...
}


Or better yet, since you seem to be parsing the entire file each time, you could save the necessary reduced data instead of the raw lines of the file, and save both memory and parsing time for subsequent files.
...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 ($).

StarGeek

Quote from: Phil Harvey on March 04, 2015, 07:25:17 AM
Or better yet, since you seem to be parsing the entire file each time, you could save the necessary reduced data instead of the raw lines of the file, and save both memory and parsing time for subsequent files. 

This is actually what I was planning on doing next.  It's actually going to be required.  I had assumed that the .picasa.ini file had the contact list at the top, since that is what I saw in my tests.  But checking with other directories, it seems that it can appear anywhere in the file.  That led to regions that didn't have names attached to them.

Additionally, since each directory would have a different .picasa.ini, I'll have to make sure to check that the directory hasn't changed.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Quote from: StarGeek on March 04, 2015, 10:27:33 AM
Additionally, since each directory would have a different .picasa.ini, I'll have to make sure to check that the directory hasn't changed.

My code shows one way to do this.

- Phil
...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 ($).

StarGeek

Quote from: Phil Harvey on March 04, 2015, 11:13:46 AM
My code shows one way to do this.

D'oh! 

I think I just about have it.  There's still one error to work out, then I want to test it a bit, but the output data looks good. 

I've learned some good stuff going through this, but still have some things about perl I haven't been able to wrap my head around.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

One source of confusion when writing complex ValConv expressions like this is to remember that they are evaluated in the Image::ExifTool namespace, which is why I needed to use variables like $Image:ExifTool:Xxxx.

- Phil
...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 ($).

StarGeek

Upon expanding my testing I've hit a snag.  The .picasa.ini file doesn't always contain all the person names that might be in that directory.  So I'll have to load up Picasa's  Contacts.xml file.  Which leads to two questions.

Is there a way for me to specify a path to the Contacts.xml file on the command line?  Something like -PicasaContactsFile=/path/to/contacts.xml?  Otherwise I guess it will have to be hardcoded.

Second, is there something built into ExifTool that I could use to read/parse an XML file before I go and write something?
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

The final snag is having to decode html entities.  Picasa html encodes some of the characters in the contact list.  The usual suspects such as quotes, greater/less than signs, ampersands, etc.  HTML::Entities doesn't seem to be available, so if there's not another option available, I'll have to add one in that will cover the basics.

Other than these problems, it looks like it's ready.  I tested it against a directory with 1,592 files that already had RegionInfo and RegionInfoMP tags which were previously inserted with AvPicFaceXmpTagger and the conversion user tags.  I compared them by truncating the numbers down 6 decimal places. That gave me 170 files that were off by .000001.  Truncating down to 5 decimal places gave only 7 were off by .00001 and those were the difference between numbers like 0.09131 and 0.0913099.  Since these differences are less than a fraction of a pixel size (unless the picture is huge), I wouldn't think they are worth worrying about.

Other than these issues, it's just about ready for use.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Hi StarGeek,

Quote from: StarGeek on March 05, 2015, 03:37:02 PM
Is there a way for me to specify a path to the Contacts.xml file on the command line?

I was actually thinking about this when you started this thread.  There may be a way (by creating a user-defined Writable Composite tag to set this path).  It will be a bit tricky though, and I've never tried it before.  Also, I'll be away tomorrow, so I won't be able to help with this until the weekend.

QuoteSecond, is there something built into ExifTool that I could use to read/parse an XML file before I go and write something?

You could create a new Image::ExifTool object, and call ImageInfo with a reference to the XML data.  This is quite do-able.

Quote from: StarGeek on March 05, 2015, 06:46:28 PM
The final snag is having to decode html entities.  Picasa html encodes some of the characters in the contact list.  The usual suspects such as quotes, greater/less than signs, ampersands, etc.  HTML::Entities doesn't seem to be available, so if there's not another option available, I'll have to add one in that will cover the basics.

Sure, just do this:

require Image::ExifTool::HTML;
my $unescaped = Image::ExifTool::HTML::UnescapeHTML($val);


QuoteOther than these problems, it looks like it's ready. [...]

Excellent!

- Phil
...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 ($).

StarGeek

Quote from: Phil Harvey on March 05, 2015, 07:37:13 PM
There may be a way (by creating a user-defined Writable Composite tag to set this path).  It will be a bit tricky though, and I've never tried it before.  Also, I'll be away tomorrow, so I won't be able to help with this until the weekend.

If you think it's tricky, then I have no clue where to even start.  I'm already messing with forces beyond my comprehension :D

QuoteYou could create a new Image::ExifTool object, and call ImageInfo with a reference to the XML data.  This is quite do-able.

I played around with this but wasn't able to get anything to work until I altered the file.  Picasa doesn't put the declaration(?) at the top of the file.  When I added that, I was able to get some output, but I don't think it'll be within my ability to deal with it.  Here's a short example of a contacts.xml file:
<contacts>
<contact id="423ab0d97fa066db" name="George" modified_time="2015-03-05T13:30:35-08:00" local_contact="1"/>
<contact id="520b28d9aa4039aa" name="Andy" modified_time="2015-03-02T11:17:20-08:00" local_contact="1"/>
<contact id="25e26bd972416fa1" name="Ed" modified_time="2015-03-02T11:17:20-08:00" local_contact="1"/>
</contacts>


I'm currently reading it line by line and using a simple regex to pull out the id and name.  It works well enough. 

Unless someone else really wants to play with it, I'll wait until you get back and can give me some clues on the user-defined Writable Composite tag idea before I post it.  That will give me some time to put it to work and see if any other bugs pop up.   Plus I want to create a version that will filter out the unknown names (where Name=ffffffffffffffff).

Thanks for all your help!
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Hi StarGeek,

Quote from: StarGeek on March 05, 2015, 10:12:00 PM
If you think it's tricky, then I have no clue where to even start.  I'm already messing with forces beyond my comprehension :D

That's how we learn. :)  I've been really impressed with your ingenuity so far.

I've added a new UserParam API option to ExifTool 9.89 that will make this easier.  The syntax is:

exiftool -api userparam=PicasaContactsFile=/path/to/contacts.xml

(I thought about adding a -userparam exiftool option to make this simpler, but I'll hold off for that now since you can go through the -api option, even though it is a bit confusing with the two equal signs.)

Then in your ValueConv, you can access this via $self->Options(UserParam => 'PicasaContactsFile');

Also, you can access it in any expression involving tag names with $picasacontactsfile.

Quote
QuoteYou could create a new Image::ExifTool object, and call ImageInfo with a reference to the XML data.  This is quite do-able.

I played around with this but wasn't able to get anything to work until I altered the file.  Picasa doesn't put the declaration(?) at the top of the file.  When I added that, I was able to get some output, but I don't think it'll be within my ability to deal with it.  Here's a short example of a contacts.xml file:
<contacts>
<contact id="423ab0d97fa066db" name="George" modified_time="2015-03-05T13:30:35-08:00" local_contact="1"/>
<contact id="520b28d9aa4039aa" name="Andy" modified_time="2015-03-02T11:17:20-08:00" local_contact="1"/>
<contact id="25e26bd972416fa1" name="Ed" modified_time="2015-03-02T11:17:20-08:00" local_contact="1"/>
</contacts>


I'm currently reading it line by line and using a simple regex to pull out the id and name.  It works well enough. 

Yeah, XML is a pain.  Doing this with ExifTool may not be any easier since this XML structure doesn't map into unique tag names.  You would have to deal with duplicate tags with names like ContactsContactId and ContactsContactName.

- Phil
...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 ($).

StarGeek

Is it possible to access the ExifTool version number without adding it to Require part of the tag?  The contact file loading is in a subroutine I'd prefer to access it directly if possible.

I want to try and keep this as compatible as possible and not force an upgrade for a feature that not everyone would use.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Sure.  Just use the value of $Image::ExifTool::VERSION directly.

- Phil
...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 ($).

StarGeek

Ok, I'd say this is ready for use.  It now has a version check so it can check to see if there's an userparam api call.  I would like to move that into the LoadContacts subroutine, but couldn't figure out how to access the userparam variable from with the subroutine.

Take a look, laugh at my coding techniques, fold, spindle, mutilate at will.

Documentation:

This ExifTool config file contains four tags that can be used to read .picasa.ini files, extract the face region info, and create MWG region tags (Media Work Group region, used by Picasa) and MP region tags (used by Microsoft Photo Library).  Before use, the path to Picasa's contacts.xml must be corrected, or if using ExifTool  9.89 or higher is used, it can be set on the command line with -api userparam=PicasaContactsFile=/path/to/contacts.xml
Tags:
-----
PicasaToMWGRegion : This will create the MWG region tag.
   Suggested Usage: ExifTool -config \path\to\.Picasa_Conversion_Config -if "$PicasaToMWGRegion" "-RegionInfo<PicasaToMWGRegion" <FILE/DIR>
PicasaToMPRegion  : This will create the MP region tag.
   Suggested Usage: ExifTool -config \path\to\.Picasa_Conversion_Config -if "$PicasaToMPRegion" "-RegionInfoMP<PicasaToMPRegion" <FILE/DIR>
PicasaToMWGRegionFiltered : This will create the MWG region tag but will filter out the regions that are still unnamed in Picasa.  Picasa defaults to naming these regions 'ffffffffffffffff'.
   Suggested Usage: ExifTool -config \path\to\.Picasa_Conversion_Config -if "$PicasaToMWGRegionFiltered" "-RegionInfo<PicasaToMWGRegionFiltered" <FILE/DIR>
PicasaToMPRegionFiltered  : This will create the MP region tag but will filter out the regions that are still unnamed in Picasa. Picasa defaults to naming these regions 'ffffffffffffffff'.
   Suggested Usage: ExifTool -config \path\to\.Picasa_Conversion_Config -if "$PicasaToMPRegionFiltered" "-RegionInfoMP<PicasaToMPRegionFiltered" <FILE/DIR>

This config file should probably be kept separate and not integrated into the main .ExifTool_config, as it would slow down regular processing of files.

If both MWG and MP region tags are desired, the commands can be combined
ExifTool -config \path\to\.Picasa_Conversion_Config -if "$PicasaToMWGRegion" "-RegionInfo<PicasaToMWGRegion" "-RegionInfoMP<PicasaToMPRegion" <FILE/DIR>
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Looks good!  Just a few minor notes:

1) You can access $Image::ExifTool::VERSION in your subroutine in just the same way as you are doing in your ValueConv.

2) In your LoadContacts() subroutine, you open CONTACTS, but close INI.  Also, you should add "local *CONTACTS" to avoid name conflicts with CONTACTS elsewhere.

3) You shouldn't need the -if option in your command, because there will be nothing to copy if the tag doesn't exist, so the effect is the same.

4) You are no longer using @Image::ExifTool::myIniData, so you can remove this line.

5) You may not need to copy the entire FileHash entry into @TempArray.  Instead, just use a reference to the array:

my $TempArrayRef = $Image::ExifTool::FileHash{$Filename} or return undef;
foreach my $TempHash (@$TempArrayRef) {
...
}


6) Similarly, you should try to avoid copying the entire contact hash if you can, by doing something like this:

my $ContactHashRef = \%Image::ExifTool::ContactHash;
...
Name => $ContactHashRef->{$TempHash->{'ContactID'}},
...


- Phil
...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 ($).

StarGeek

Quote from: Phil Harvey on March 08, 2015, 09:40:03 AM
1) You can access $Image::ExifTool::VERSION in your subroutine in just the same way as you are doing in your ValueConv.

At first I tried to have this whole part in the LoadContacts subroutine:
my $ContactFile = $Image::ExifTool::ContactXML;
if ($Image::ExifTool::VERSION >= 9.89)
{
if (defined($self->Options(UserParam => 'PicasaContactsFile')))
{
$ContactFile = $self->Options(UserParam => 'PicasaContactsFile');
}
}


The problem I had was accessing $self->Options(UserParam => 'PicasaContactsFile');.  In the LoadContacts subroutine it had no value.   Entirely possible I had something else wrong though.

Hmmm, I could replace it with
my $ContactFile = ($Image::ExifTool::VERSION >= 9.89 and defined($self->Options(UserParam => 'PicasaContactsFile')))
? $self->Options(UserParam => 'PicasaContactsFile')
: $Image::ExifTool::ContactXML;

right?

Quote2) In your LoadContacts() subroutine, you open CONTACTS, but close INI.  Also, you should add "local *CONTACTS" to avoid name conflicts with CONTACTS elsewhere.
Yet another D'oh moment with the closing.  Obviously I copy/pasted the other subroutine as the base.  Too inexperienced to know about local.  I don't think I have any other CONTACTS, but added it just in case.

Quote3) You shouldn't need the -if option in your command, because there will be nothing to copy if the tag doesn't exist, so the effect is the same.
Maybe it's a Windows executable thing, but without it I get a "Warning: No writable tags set from..." warning.  I was trying to avoid that.

Quote4) You are no longer using @Image::ExifTool::myIniData, so you can remove this line.
Another D'oh.  Done.

Quote5) You may not need to copy the entire FileHash entry into @TempArray.  Instead, just use a reference to the array:

my $TempArrayRef = $Image::ExifTool::FileHash{$Filename} or return undef;
foreach my $TempHash (@$TempArrayRef) {
...
}


6) Similarly, you should try to avoid copying the entire contact hash if you can, by doing something like this:

my $ContactHashRef = \%Image::ExifTool::ContactHash;
...
Name => $ContactHashRef->{$TempHash->{'ContactID'}},
...

Yeah, this is especially where I'm messing with stuff I'm not fully comprehending.   I spent an hour or so pounding at this like a Klingon engineer (keep hitting it until it works!!).  I had Dumper showing me what was in the variables, I could see where the problem was, but I had problems figuring out the proper way to fix it.  At that point it became all about making it work regardless of the consequences!

Updated version attached.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Quote from: StarGeek on March 08, 2015, 05:10:08 PM
The problem I had was accessing $self->Options(UserParam => 'PicasaContactsFile');.  In the LoadContacts subroutine it had no value.

Ah, yes.  You would need to pass $self into the subroutine so it could access the ExifTool object from there.

QuoteMaybe it's a Windows executable thing, but without it I get a "Warning: No writable tags set from..." warning.  I was trying to avoid that.

Ah, yes.  Not a Windows thing.  The -if will avoid the warning.

- Phil
...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 ($).

Phil Harvey

I hope you don't mind, but I have edited your config file with an eye towards eventually including it in an ExifTool distribution.  To this end, many of the changes are purely aesthetic, and attempt to make the coding style conform more to that of ExifTool.

I have also changed some variable names and scoping to avoid possible future conflicts with ExifTool variables.

And I took the liberty to change the output 'ffffffffffffffff' name to 'unnamed', to be a bit nicer for the user.  Feel free to change this back if you wanted to leave it as 'ffffffffffffffff'.

Attached is my edited version.  I don't have the necessary Picasa files to test this, so I can't be sure that I didn't mess something up with my changes.

- Phil
...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 ($).

StarGeek

Quote from: Phil Harvey on March 10, 2015, 08:52:20 AM
I hope you don't mind, but I have edited your config file with an eye towards eventually including it in an ExifTool distribution.  To this end, many of the changes are purely aesthetic, and attempt to make the coding style conform more to that of ExifTool.
Sounds good.  I would have been surprised if you didn't.  Feel free to edit and clarify anything you think needs to be fixed.

QuoteAnd I took the liberty to change the output 'ffffffffffffffff' name to 'unnamed', to be a bit nicer for the user.  Feel free to change this back if you wanted to leave it as 'ffffffffffffffff'.

This is something I thought about and couldn't decide upon a satisfactory solution.

Picasa normally won't store the unknowns in the file.  But if you use AvPicFaceXmpTagger, it will add the unknowns using the 'ffffffffffffffff' name.  So if Picasa has to reload a file due to a corrupt database or something similar, it will add this as a name.  'ffffffffffffffff' does stand out as something out of the ordinary and forces you to deal with it, but 'unnamed' is nicer to look.  Hmmm... I should check to see if Picasa leaves it in the file if tell Picasa to ignore that region. 

All this is basically why I use the filtered versions and just included the non filtered ones for completeness.  Maybe the names should be swapped.  Named the filtered versions with the basic name for regular use, since this would match how Picasa adds tags, and add "Unfiltered" or something similar to what are currently the basic tags. 

As a side note, Picasa does read the MPRegion tags seems to process them faster than the MWG Region tags.  When I added files that contained only one or other, it recognized regions in the file with the MPRegions instantly upon loading, but didn't recognize the MWG regions until I closed and restarted Picasa.

QuoteAttached is my edited version.  I don't have the necessary Picasa files to test this, so I can't be sure that I didn't mess something up with my changes.

I'll test it out.

There was one more tag (or maybe tags, filtered and unfiltered) I was going to add.  I was thinking about a adding a list type tag that was just the region names, so that way they could also be added to XMP:Subject and IPTC:Keywords in the same command, rather than adding the regions to a file then running -Subject<RegionName as a separate command.  This would also allow running an update on the files if needed.  Something like -if "$RegionName ne $PicasaIniRegionNames" "-RegionInfo<PicasaToMWGRegionFiltered".  Because, unless I'm mistaken, you can't use -if "$RegionInfo ne $PicasaToMWGRegionFiltered" to check for changes, correct?  At least my tests along those lines didn't work.


* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

Quote from: Phil Harvey on March 10, 2015, 08:52:20 AM
Attached is my edited version.  I don't have the necessary Picasa files to test this, so I can't be sure that I didn't mess something up with my changes.

Something did break.   Under ExifTool version 9.67, it appears that 0 is being passed for various x and y coordinates.  Under  9.89, it responds with "Warning: ValueConv PicasaToMWGRegionFiltered: Can't call method "Options" on an undefined value".

Output of my old config using ver 9.67
c:\Server\My_stuff>exiftool -config C:\Programs\UnixUtils\.Picasa_Conversion_Config -struct -PicasaToMWGRegionFiltered -PicasaToMPRegionFiltered Z:\Pictures\Camera_Pictures\Camera_Pictures_Finished\Camera-Final\Comikaze_Expo\2012\2012-09-15_15.34.23.Jpg
Picasa To MWG Region Filtered   : {AppliedToDimensions={H=4928,Unit=pixel,W=3264},RegionList=[{Area={H=0.1331045,Unit=normalized,W=0.1678951,X=0.57077135,Y=0.13900205},Name=LeeAnna Vamp,Type=Face},{Area={H=0.1406119,Unit=normalized,W=0.1761654,X=0.38159,Y=0.20464635},Name=Jessica Nigri,Type=Face}]}
Picasa To MP Region Filtered    : {Regions=[{PersonDisplayName=LeeAnna Vamp,Rectangle=0.4868238|, 0.0724498|, 0.1678951|, 0.1331045},{PersonDisplayName=Jessica Nigri,Rectangle=0.2935073|, 0.1343404|, 0.1761654|, 0.1406119}]}


Output of your config using ver 9.67, which is passing the names properly but not the X, Y, W, and H variables
c:\Server\My_stuff>exiftool -config C:\Programs\UnixUtils\.Picasa_Conversion_Config_Phils -struct -PicasaToMWGRegionFiltered -PicasaToMPRegionFiltered Z:\Pictures\Camera_Pictures\Camera_Pictures_Finished\Camera-Final\Comikaze_Expo\2012\2012-09-15_15.34.23.Jpg
Picasa To MWG Region Filtered   : {AppliedToDimensions={H=4928,Unit=pixel,W=3264},RegionList=[{Area={H=0,Unit=normalized,W=0,X=0,Y=0},Name=LeeAnna Vamp,Type=Face},{Area={H=0,Unit=normalized,W=0,X=0,Y=0},Name=Jessica Nigri,Type=Face}]}
Picasa To MP Region Filtered    : {Regions=[{PersonDisplayName=LeeAnna Vamp,Rectangle=|, |, 0|, 0},{PersonDisplayName=Jessica Nigri,Rectangle=|, |, 0|, 0}]}


And output of your config with ver  9.89
c:\Server\My_stuff>exiftool_9.89 -config C:\Programs\UnixUtils\.Picasa_Conversion_Config_Phils -struct -PicasaToMWGRegionFiltered -PicasaToMPRegionFiltered Z:\Pictures\Camera_Pictures\Camera_Pictures_Finished\Camera-Final\Comikaze_Expo\2012\2012-09-15_15.34.23.Jpg
Warning: ValueConv PicasaToMWGRegionFiltered: Can't call method "Options" on an undefined value - Z:/Pictures/Camera_Pictures/Camera_Pictures_Finished/Camera-Final/Comikaze_Expo/2012/2012-09-15_15.34.23.Jpg


I'll PM you a link with sample contacts.xml, .picasa.ini and image file.

Yeah, and have a laugh at my directory structure.  I blame you Phil, because every time I learn some new and exciting way to use ExifTool, I start moving files to a new directory to keep track of what files have "completed" metadata and which don't.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Quote from: StarGeek on March 10, 2015, 02:35:52 PM
unless I'm mistaken, you can't use -if "$RegionInfo ne $PicasaToMWGRegionFiltered" to check for changes, correct?

Right.  That won't work.

I'll have to wait until tomorrow before I can take a look to see what I broke.  Writing complex code in ValueConv expressions is difficult because ExifTool hides the normal compile and runtime errors/warnings.

- Phil
...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 ($).

Phil Harvey

#24
Thanks for the test files.

Yes, I did mess up a few things!!  There is no substitute for actually running the code... ;)

I also fixed a problem in your original version which prevented it from working on my system due to different newlines.

Attached is an updated version that works for me now.

Post back here after you have made any additional additions/improvements that you want.  When you are done, I'll go through the code once more to make the style ExifTool-like, then add it to the distribution.

- Phil

Edit: Changed the ValueConv expressions to code references.  This has a few advantages in this situation:

1) The code is no longer evaluated in the ExifTool namespace, so we can avoid creating Image::ExifTool variables.

2) The code is only compiled once when it is loaded.

3) Any compile problems are easier to track down.
...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 ($).

StarGeek

This version passes the numbers correctly, but now the region names are showing up empty for me.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Hmmm.  It works for me.  :(  Does the exact same command work with your version but not mine?  The opposite is true for me because "chomp" doesn't remove what it needs to when parsing your contacts file on this platform.

Here is the command I used:

exiftool -config ~/Desktop/Picasa_Conversion_Config ../testpics/Picasa/testfiles/ -api userparam=PicasaContactsFile=../testpics/Picasa/testfiles/contacts/contacts.xml -picasa'*' -r -struct

If you don't get the names, it is probably because the contacts file isn't getting processed somehow.  Darn.

I'll debug this on Windows, but can't do this until tomorrow.

- Phil
...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 ($).

StarGeek

Sorry, another of my stupid mistakes.  I realized the moment I saw your command that I had forgot to change the path to the contacts.xml file in your file I downloaded or set the userparam.

I've made a few minor changes.  I've changed the tag names so that the basic tag is filtered, and added Unfiltered to the names of the original tags.  This more closely mimics the behavior of Picasa rather than the behavior of AvPicFaceXmpTagger.  The more I thought about this, the more I felt this was a better choice.  If 'unnamed' or 'ffffffffffffffff' region is added to the file, Picasa will add that as a contact name, where normally it would leave it blank. 

I also added PicasaRegionNames.  This will allow for easy copying of the region names into tags such as keywords and subject.  It also allows easy updating of a full directory when changes are made.  It worked quite well last night.  I was tagging a directory, run an update in the background every now and then, and keep tagging while it ran.  This process makes me very happy, as it's much easier and quicker than my previous workflow.

Take a look at PicasaRegionNames but you shouldn't have to change anything, as all I did was copy/paste your version of PicasaToMPRegion, remove a bunch of lines and change about two lines.  I didn't include an unfiltered version, but it would be simple to add if needed.

Thanks for all your help, I'm quite happy with the way this has worked out.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

I gave this config file a heavy workout today (well, yesterday at this point).  I kept running it in the background while I was tagging a bunch of directories, many of which already were tagged in Picasa, a few which already had the regions written into the files.  A bit over 39 K files in the directories, 10 K which ended up with region tags.   Only one error popped up a few times and that wasn't something that was ExifTool's fault.  Speed was much better than I expected.  Short version, results look very promising.  Tomorrow, I'll make a copy of a few of those folders, add them to a new Picasa database, let Picasa do its thing, and see if anything really bad shows up.


Long version with useless talk about the error:
The one error I came across, "Warning: No writable tags set", has to do with the way Picasa deals with zone data.  If there is already region data in the file, that data has priority and nothing is written to the .picasa.ini.  So there was no PicasaToMWGRegion or PicasaToMPRegion tags created from the .picasa.ini but the command I was using was doing a check that tested true (-if "$RegionName ne $PicasaRegionNames").  So, RegionName already existed in the file, Picasa didn't write it to the .picasa.ini file, and ExifTool has an undefined PicasaRegionNames and obviously, no PicasaToMWGRegion and PicasaToMPRegion tags to write.  Not a big deal, of course.

The good news is that if a new zone is added in Picasa to a file that already has tags, then the new data plus the old data is written to the .picasa.ini file, allowing this config file to update the image with the new zones.  I will have to check to see what happens if one of the zones already defined in the file ignored and see what changes happen.


* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

#29
Quote from: StarGeek on March 11, 2015, 07:15:01 PM
I realized the moment I saw your command that I had forgot to change the path to the contacts.xml file in your file I downloaded or set the userparam.

Great.  I also realized that my attempted warning isn't working to print a message when the contacts file can't be opened.  I'll look into this.

It sounds like it is working well for you.  Excellent. 

- Phil

Edit:  I was playing with the new version.  I wonder how it is best to handle the case where a name is not found (ie. contact.xml not loaded).  I think I changed the behaviour so that it now returns nameless regions, but maybe that was the wrong thing to do.  Would it be better to return no region at all if there is no person name?

Edit2: OK.  I've gone ahead and implemented this for the filtered regions (returns no region if no name), which sort of makes sense to me.  I have also gone through and finished prettying up the code to match the ExifTool comment style, and changed the config file name to what I would like to use in the distribution.  I see this as good to go for the next release unless you want anything changed.  Attached is the updated version.
...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 ($).

StarGeek

Sorry for delay in getting back to this.

Sounds like it's all nice and shiny now.

I created a new Picasa database and dropped in about 1,500 files that had the region tags already inserted.  There wasn't any obvious errors in how Picasa read the tags in and I even found one case where I had named something incorrectly, so it helped me fix an error.  So that makes me even more confident that the math is correct, not that I was very worried about it in the first place.  Looks like it's ready for real use.

I've downloaded you newest copy and I'll be giving it some heavy usage today.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Glad to hear, because I've included it in the production ExifTool 9.90 release issued this morning. :)

- Phil
...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 ($).

milchtaich

This works beautifully, with one exception: RAW files in portrait orientation.
The root of the problem is the exception Picasa makes for RAW files that, according to the Exif Orientation tag, need to be rotated. In any other case, the origin of the image is the top-left corner of the stored, unrotated image. This is in accordance with the MWG standard, so everything is good. However, for some reason, for RAW files Picasa views the top-left corner of the rotated image as the origin, and computes the coordinates stored at the INI file accordingly. This creates a problem when the -RegionInfo<PicasaToMWGRegion command is used for writing the MWG area information to an XMP sidecar. Lightroom 6 reads the information off that file and draws the rectangle at the wrong place, even though it exactly follows the standard.
This error may be prevented by changing the logic of the command to accommodate Picasa's peculiarity described above when dealing with RAW files whose orientation is not Horizontal.

Igal Milchtaich

StarGeek

Shame on me for not testing rotated images (one of my first steps is to losslessly rotate my jpgs).   And shame on me for assuming that Picasa will do the right thing in the first place.

I'm pretty sure that Picasa doesn't read region data from NEF or CR2 so any fix can ignore what Picasa does and just write correct data. 

It's cool that LR6 is reading region data.  Does it read it if it's embedded in the file or only from external xmp? 

Am I correct in thinking that this is what's required to rotate a region?
Rotate 90
X=1-H-Y
Y=X
Swap Width and Height.

Rotate 180
X=1-W-X
Y=1-H-Y
(no change to W and H)

Rotate 270
X=Y
Y=1-W-X
Swap Width and Height.

I did some quick checking and couldn't see any details on how Microsoft regions dealt with image orientation.

* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

milchtaich

@StarGeek,
Lightroom 6 reads MWG region information from JPGs, RAW files and XMP sidecars of RAW files. This is indeed an exciting development that makes your work timely and valuable to many photographers. Note that the problem I described only concerns RAWs. JPGs are not affected, regardless of their orientation.

The corrections that need to be applied I believe are the following. (The left-hand side are the corrected values, those used on the right-hand side are the uncorrected ones – the current output of -RegionInfo<PicasaToMWGRegion).

Rotate 90
X=Y
Y=1-X
Swap Width and Height.

Rotate 180
X=1-X
Y=1-Y
(no change to W and H)

Rotate 270
X=1-Y
Y=X
Swap Width and Height.

Microsoft lives in a fool's paradise: it completely ignores orientation. In the present context, this is good. One thing I noticed at the time was that their published specification did not match their practice. In the Rectangle quartet, the first and second entries are respectively the x and y coordinates of the top-left corner of the rectangle (rather than the reverse order, y and x) and the third and fourth entries are respectively the W and H of the rectangle (rather than H and W, in that order, which is what the http://ns.microsoft.com/photo/1.2/ scheme specifies). However, I do not work with the Microsoft scheme and did not try the -RegionInfoMP<PicasaToMPRegion command, so this observation should be taken with a grain of salt.

Igal Milchtaich 

StarGeek

Sorry it took so long to get back to this.

I think I have this corrected now, but only for NEF and CR2 at the moment, since those are the only raw file types I have on hand at the moment.  I plan on looking for other raw file types that Picasa supports and if anyone has a rotated one where Picasa detects a face and is willing to share, it'd be appreciated.

It's only had limited testing so far, so use at your own risk.  I also don't have LR6 so I can't see if that's going to be correct.  I had to compare the results from the raw files to the corresponding jpg.  Also I didn't deal with the more unlikely orientations such as Mirror vertical or Mirror horizontal.

Additionally, I created a config file that can be used to rotate the regions in a file.   These are RotateMWGRegionCW90 (or 180/270) and RotateMPRegionCW90 (or 180/270).  The commands for those would be exiftool -config Rotate_Regions.config "-RegionInfo<RotateMWGRegionCW90" FILE or something similar.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

This is great, thanks!

I've cleaned up the picasa_faces.config file a bit.  Let me know what you think.

- Phil
...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 ($).

milchtaich

The latest, 2015/05/12 version of picasa_faces.config works well also for Sony ARW files (as does the 2015/05/11 version, with this file type added to RawFileTypes), with images rotated 0°, 90° or 270°. Very nice!

More often than not, Lightroom 6 reads the region data that ExifTool writes to the sidecar XMP files and shows the face rectangles and names. Why it doesn't always do so I don't know, but my suspicion is that the problem is something else than the region metadata. The whole face tagging business in LR is a work in progress.

StarGeek

#38
I just tested a DNG and verified that it needs to be on the isRawFile list.  So that means that CRW, ERF, MEF, MRW, NRW, ORF,  SRW, and  X3F are untested.  Though in all probability they will need to be on there.

Edit: Found a PEF.  Its EXIF was a bit messed up but after fixing that, it worked properly with the new config.  I'll keep looking around until I catch 'em all.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

#39
Thanks to user Evds for pointing out a problem with this.

Due to the nature of floating point numbers, sometimes the Height and Width variables end up being extremely long, for example, something like 0.0567941000000001.  There seems to be a limit to how large a number that Picasa will read in and it will not reload regions with long decimals like this.

The fix is easy though.  Lines 153 and 154 need to be changed from
                W => $x1 - $x0,
                H => $y1 - $y0,


to
                W => int(($x1 - $x0)*10000000+.5)/10000000,
                H => int(($y1 - $y0)*10000000+.5)/10000000,


edit: Too many parens, fixed.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Great.  I'll make this change in the distributed config file.

Thanks.

- Phil
...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 ($).

StarGeek

#41
A minor adjustment to the code for this config file.  I finally took time to figure out exactly the degree of precision that Picasa would start ignoring regions.  If the regions were 10 decimal places or greater, then the regions would not be applied.  So here's my suggestion on changes to lines 144 to 154.  The comment has been moved, the earlier rounding operations have been moved, and the rounding precision extended from 7 decimals to 9 decimals.
            my $x0 = ($hi >> 16)   /65535;
            my $y0 = ($hi & 0xffff)/65535;
            my $x1 = ($lo >> 16)   /65535;
            my $y1 = ($lo & 0xffff)/65535;
            push @{ $fileHash{$section} }, {
                ContactID => $2,
# round to 8 decimals (Picasa will ignore regions with greater than 10 decimals)
                X => int($x0*100000000+.5)/100000000,
                Y => int($y0*100000000+.5)/100000000,
                W => int(($x1 - $x0)*100000000+.5)/100000000,
                H => int(($y1 - $y0)*100000000+.5)/100000000,,


Edit:  Changed to 8 decimals instead of 9.  Division in lines 216-217 can increase in number of decimals.

Edit 2:  Upon further thought, it might be best to move all rounding operations to the final assignment of values.  I think the RotateRegion sub has the possibility of introducing a precision problem as well.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Great, thanks.  This update will appear in the next release.

- Phil
...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 ($).

StarGeek

One (hopefully) final update to this config.  The rounding operation has been moved to a subroutine, so you don't need to search throughout the config if you want to make adjustments.  Rounding is now made after all the math operations are done, so there should be no more chance of floating point errors.  Precision increased to max that Picasa can use.  No real point to this as the difference won't amount to even a pixel in size unless your image is tens of thousands of pixels wide/high, but then again, why not.

I've done only limited testing, using 20 images that had precision problems under previous versions, and those came out correctly. 

On regular camera images, this seems to be a very rare error.  I checked some of my pictures I used the older config on and out of a little over 93,000 images that I had tagged, only 586 pictures had this error.

However, on random images I had downloaded from the net, the error margin seemed much higher, maybe about 5%.  Though those are much more varied in image dimensions, so that may have something to do with it.


The second attached config file will correct rounding errors on previous images.  It includes the tags CorrectedMPRegion and CorrectedMWGRegion which can be redirected into RegioninfoMP and Regioninfo.  The command I'm using to fix previous errors is this:
exiftool -config Correct_Region.config -struct -if "$CorrectedMWGRegion or $CorrectedMPRegion" "-RegionInfo<CorrectedMWGRegion" "-RegionInfoMP<CorrectedMPRegion" DIR
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Great, thanks.  The updated config file will appear in the next release.

- Phil
...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 ($).

benthos

Hi Guys,

thanks for the great work, I've been trying to import my face tags from Picasa to Lightroom 6 for the past week when I came upon your thread!! Magic it works... for the most part.

I've been testing on a DNG with 8 people tagged in it.
If I run:
exiftool.exe "-RegionInfo<PicasaToMWGRegion" test_picasa.DNG
the Regions get imported, and all 8 faces are flagged as "named" in Lightroom

But when I also try to import the Keywords using
exiftool.exe "-RegionInfo<PicasaToMWGRegion" "-XMP-dc:Subject+<PicasaRegionNames" test_picasa.DNG
Lightroom shows me 2 faces "named" and 6 faces "unnamed". The regions are transferred, but only 2 of the names!

I also tried "-MWG:Keywords", "-XMP:Subject" and "-IPTC:Keywords" (using either '<' or '+<')

Am I doing something wrong?

P.S. Using Exiftool 10.21 with the picasa_faces.config distributed with that version
I will try to reproduce the problem with an image, .picasa.ini and contacts.xml file I can share

Thanks

Phil Harvey

Presumably the region names are transferred in the 2nd command, but somehow writing XMP:Subject is interfering with Lightroom's display of the region names?  I don't see how this could happen.  A sample would be very useful.

- Phil
...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 ($).

benthos

Ok,

  I recreated the problem with a minimum data files. Attached is the picasa.ini file of the folder and the contacts.xml that was used. I'll try to upload the DNG in a seperate post to make sure if fits


Even compressed, the DNG file is too big, so here's a link to it: https://www.dropbox.com/s/op6xtd59m3pbxab/NXS50036.DNG.bz2

StarGeek

Interesting, the .xml are formatted a bit differently than the ones my picasa writes, though it doesn't look like it would affect the reading of the data.  Also, when I attempt to embed the data, it doesn't update the file, though from what I can tell, it should.

* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Hydroxia

Hi StarGeek,

I've just trying to work out the rotation commands and I noticed a potential error in your definition/examples.

Tag definitions and examples:
#
#   RotateMWGRegionCW90
#   RotateMWGRegionCW180
#   RotateMWGRegionCW270
#     These tags will rotate a MWG Region clockwise 90, 180, or 270 degrees.
#     Example:
#       exiftool -config rotate_regions.config "-RegionInfo<RotateMWGRegionCW90" FILE
#
#   RotateMPRegionCW90
#   RotateMPRegionCW180
#   RotateMPRegionCW270
#     These tags will rotate a MWG Region clockwise 90, 180, or 270 degrees.
#     Example:
#       exiftool -config rotate_regions.config "-RegionInfoMP<RotateMPRegionCW90" FILE

Shouldn't the second one read "These tags will rotate a MP Region clockwise 90, 180, or 270 degrees"?

I'm new to the forum I didn't know if I should just start a new thread just for me being pedantic. This is where I found out about your file and commands. Thanks.

Phil Harvey

... makes sense to me.  I'll update this comment in the next release.

- Phil
...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 ($).