Author Topic: Recognizing list-type fields  (Read 2397 times)

yosh

  • Jr. Member
  • **
  • Posts: 16
Recognizing list-type fields
« on: May 17, 2017, 11:19:47 AM »
Hey, I'm trying to make an action that handles all possible IPTC moves (from single record to single, single to list-type, list-type to single (joined) and list-type to list-type). The problem is when I try to move one list-type record into another list-type record that has only one value, i.e. put all keywords into by-line tags. So in fact I want to change all 2:25 (1C 02 19) to 2.80 (1C 02 50).

Is there a fast way to tell if the destination record is of list-type by standard, and not check it's current values?

Currently trying something like this but the destination isn't always of type 'ARRAY'.
Code: [Select]
if (ref $record_from eq 'ARRAY' && ref $record_to eq 'ARRAY') {
       foreach (@$record_from) {
     $exifTool->SetNewValue($record_too, $_, AddValue => 1);
     $exifTool->SetNewValue($record_from, $_, DelValue => 1);
       }
}

Or maybe there is a better way and I don't have to check the type of source and destination fields? :)

Also, bonus question.... Is it safe to use this solution to get tag names by number?
Code: [Select]
my $record = 2;
my $number = 80;
my $tagname = Image::ExifTool::GetTagTable( $Image::ExifTool::IPTC::Main{$record}{SubDirectory}{TagTable} )->{$number}{Name}; #= By-line

Thanks in advance!

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 15224
    • ExifTool Home Page
Re: Recognizing list-type fields
« Reply #1 on: May 17, 2017, 04:07:34 PM »
How are you joining the lists?  If you can join them so they can be split again, you can just do this:

Code: [Select]
$exifTool->Options(List => 0);
$exifTool->Options(ListSep => ', ');
$exifTool->Options(ListSplit => ', ');
# then just do this for all tags:
$exifTool->SetNewValue($tag, $val);

If it is a List-type tag, then the value will be split apart again.

For the bonus:  It really isn't safe in that you are accessing private ExifTool data structures, but these aren't likely to change so your code should work for the foreseeable future.

You shouldn't, however, use a table without calling GetTagTable() first.  So you should do this:

Code: [Select]
my $record = 2;
my $number = 80;
my $iptcTable = Image::ExifTool::GetTagTable('Image::ExifTool::IPTC::Main');
my $tagname = Image::ExifTool::GetTagTable( $iptcTable{$record}{SubDirectory}{TagTable} )->{$number}{Name}; #= By-line

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

yosh

  • Jr. Member
  • **
  • Posts: 16
Re: Recognizing list-type fields
« Reply #2 on: May 19, 2017, 04:47:25 AM »
Thank you! I am testing it now and it seems to work great.

I have another question though. Is there a method like "commit" or "update" that updates the metadata in memory before writing it to file?

I allow users to define a list of actions to perform. For example:

1) Delete keywords
Code: [Select]
$exifTool->SetNewValue('Keywords');2) Set new keyword
Code: [Select]
$exifTool->SetNewValue('Keywords', 'word1');3) Add new keyword
Code: [Select]
$exifTool->SetNewValue('Keywords', 'word2', AddValue=>1);
This results in all the previously deleted keywords being brought back. Is there any sync/update method to call? SaveNewValues() called after each action doesn't seem to do that.

Also fixed the IptcTable to include calling that method, thanks!

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 15224
    • ExifTool Home Page
Re: Recognizing list-type fields
« Reply #3 on: May 19, 2017, 07:20:04 AM »
I think you are confused about the function of AddValue.  This is only used to preserve existing entries in the file.

If you want to replace existing keywords with "word1", "word2", just do this:

Code: [Select]
$exifTool->SetNewValue(Keywords => 'word1');
$exifTool->SetNewValue(Keywords => 'word2');

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

yosh

  • Jr. Member
  • **
  • Posts: 16
Re: Recognizing list-type fields
« Reply #4 on: May 22, 2017, 04:06:25 AM »
No, I understand how AddValue works.
Just hoped I could do something to use it without bringing back previously deleted content of that record.

This is great, thank you!

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 15224
    • ExifTool Home Page
Re: Recognizing list-type fields
« Reply #5 on: May 22, 2017, 05:30:07 PM »
If you want to delete a specific value, then use DelValue.  If you want to replace all existing list values from a file, then you don't use either DelValue or AddValue.

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