Tag to write Keywords, Subject, and HierarchicalSubject

Started by StarGeek, May 19, 2018, 04:03:03 PM

Previous topic - Next topic

StarGeek

I made a tag so that when you write HierarchicalSubject, it will also write the leaf keyword to IPTC:Keywords and XMP:Subject.  So if you want to write something like "People|Family|John", it will write the full string to HierarchicalSubject and just "John" to IPTC:Keywords and XMP:Subject.  Setting -MyHS= should clear out all three tags.

It won't work with exiftool versions from 10.16 to 10.97, but should work with earlier or later versions.  Testing has been limited because of this, but it seems to work well.

StarGeek Edit: Removed old version, see updated version below

Example Output:
C:\>exiftool_10.13.exe -myhs+="People|Family|John" -myhs+="People|Family|Jane" y:\!temp\Test3.jpg
    1 image files updated

C:\>exiftool -g1 -a -s -IPTC :Keywords -XMP:Subject -HierarchicalSubject y:\!temp\Test3.jpg
---- IPTC ----
Keywords                        : John, Jane
---- XMP-lr ----
HierarchicalSubject             : People|Family|John, People|Family|Jane
---- XMP-dc ----
Subject                         : John, Jane

"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

StarGeek

I have to say that this tag is working out better than I had hoped.  I was only thinking of writing tags when I started, but didn't realize that it could also remove individual tags with -MyHS-=data.  And setting it to nothing (-MyHS=) will clear all three tags.  This will make management of HierarchicalSubject and the individual keywords much easier.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Phil Harvey

Looks great.

I'll be rolling out ExifTool 10.98 in a few days.

- 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

With more testing on 10.98, I was running into the occasional problem that only the leaf word was being added to HierarchicalSubject.  I suspect it was the fact that you can't depend upon the order of a hash and that I was changing the value of $val.  Now $val is assigned to a temp variable and the regex is performed on that and then returned. 

Original post has been updated.  Now it's time to re-write a whole lot of commands to use this.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Phil Harvey

I don't remember what your original code looked like, but I usually do sort keys %HASH to avoid the hash order problem.

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

mnaoumov

I put it inside

Quote'Image::ExifTool::Composite' => {

I tried to use it but I get

QuoteWarning: Sorry, MyHS is not writable
Nothing to do.

it has
Writable => 1

I also tried to change to
Writable => 'string'

But it doesn't help

I am using ExifTool 12.11 on Windows

Please assist

mnaoumov

Nevermind, found it

I had to put it under

%Image::ExifTool::UserDefined::xxx = (

which was not obvious (to me) :)

StarGeek

Quote from: mnaoumov on June 11, 2021, 12:16:54 PM
which was not obvious (to me) :)

Sorry, I'll have to make this easier to work with when I get a chance.  I'm trying to remember if my local copy has a fix that I may not have put into this version.  While I use this a lot, it didn't seem to have generated much interest, so I may not have kept it updated.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

StarGeek

Updated version. It now only writes IPTC tags if the IPTC group already exists.

Unlike above, this is a complete config file. To add this tag to your own .ExifTool_config, copy the section between the horizontal bars and place it underneath the
'Image::ExifTool::Composite' => {
line in your config file

#------------------------------------------------------------------------------
# File:         MyHS.config
#
# Description:  This tag allows writing a value to the HierarchicalSubject while also writing the leaf keyword
#               (the last one in the hierarchy) to XMP:Subject and optionally IPTC:Keywords if other IPTC data
#               is present.
#
#               Example command:
#                   exiftool -config MyHS.config -MyHS="People|Family|John" -MyHs="People|Family|Mary" /path/to/files/
#                   With this result, with Keywords only being written only if there was other IPTC data
#                   [IPTC]          Keywords                        : John, Mary
#                   [XMP-dc]        Subject                         : John, Mary
#                   [XMP-lr]        HierarchicalSubject             : People|Family|John, People|Family|Mary
#
# Revisions:    Ver 1.1 2018-05-19
#                   Added temp variable to avoid random hash(?) based error
#               Ver 1.2 2024-08-07
#                   Now only writes IPTC tags if the IPTC already exists, which is the equivilent to using the -wm cw option

#------------------------------------------------------------------------------

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
#------------------------------------------------------------------------------
        MyHS => {
        # Writes string to HierarchicalSubject and leaf keywords to IPTC:Keywords and XMP:Subject.
        # Requires exiftool ver 10.13 or earlier, or 10.98 or later
        # Ver 1.1
        #   Added temp variable to avoid random hash(?) based error
        # Ver 1.2
        #   Now only writes IPTC tags if the IPTC already exists, which is the equivilent to using the -wm cw option
            Require => 'XMP:HierarchicalSubject',
            Writable => 1,
            List => 'Bag',
            WriteAlso => {
                'XMP:HierarchicalSubject' =>'$val',
                'IPTC:Keywords' => q {
                        $opts{EditGroup} = 1; # To force IPTC:Keywords to always be written remove this line or comment it out with a leading #
                        return undef if not defined $val;
                        my @temp = (ref $val) ?  @{$val} : ($val);
                        s/.*(?:^|\|)([^|]*)$/$1/ for @temp;
                        return(@temp ? \@temp :undef);
                    },
                'XMP:Subject' => q{
                    return undef if not defined $val;
                    my @temp = (ref $val) ?  @{$val} : ($val);
                    s/.*(?:^|\|)([^|]*)$/$1/ for @temp;
                    return(@temp ? \@temp :undef);
                },
            },
            ValueConv => '$val',
        },
#------------------------------------------------------------------------------
    },
);
1;  #end

Edit: Strikeout doesn't work with the [code] formatting, so I removed the older version to eliminate confusion. But I made sure and copied it to Archive.org in case someone really wants to see it.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

KalyaSC

#9
Thanks for sharing your config file  :) !!

I gave it a try on macOS and it works as expected ! I have a few questions if you don't mind:

1) Is the [XMP-lr] tag/sub-tags readable by other software than Adobe Lightroom ?

2) Is the XMP:Subject the new globally accepted standard compared to IPTC:keywords ?

3) Is there any easy way to add the EXIF:XPKeywords tag into the mix in the config file ?

My general knowledge with coding is pretty limited, I get by with some basic bash scripts, but this code looks gibberish from my perspective xD (I guess this is Pearl language?). I tried to add the EXIF:XPKeywords tag but as you know better than me, this won't work by simply copying and changing XMP:Subject to EXIF:XPKeywords because as per the documentation (Yes I'm trying to show off here xD) the XPKeywords is a tag within binary data? and can't be individually added/deleted.

I tried to enclose $val between single quotes and tried to somehow manipulated the sed substitution without any success.

Can you give me some hints how I could achieve this?

Thanks again for sharing your config !

Phil Harvey

1. Yes.

2. Yes.

3.  XPKeywords is not a list-type tag, so you would just write $val without splitting into a list:

                'EXIF:XPKeywords' => q{ $val },
- 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: KalyaSC on September 28, 2024, 04:28:32 PM1) Is the [XMP-lr] tag/sub-tags readable by other software than Adobe Lightroom ?

It is if the program has been written to take advantage of it. For exmaple, Photools' IMatch will use HierarchicalSubject. I do not know if other Digital Asset Management (DAM) programs, such as ACDSee or DigiKam will use it.

Quote from: KalyaSC on September 28, 2024, 04:28:32 PM3) Is there any easy way to add the EXIF:XPKeywords tag into the mix in the config file ?
Quote from: Phil Harvey on September 28, 2024, 04:31:13 PM3.  XPKeywords is not a list-type tag, so you would just write $val without splitting into a list:

                'EXIF:XPKeywords' => q{ $val },

I don't think it's that easy. Phil's code would write a full hierarchy, i.e. the example above of People|Family|John would write all of that, not just the leaf keyword of John. Also, as Phil says, it's not a list type tag, so this will overwrite any previous values. What would have to be done is to grab any existing value and append the leaf keyword prefixed by a semicolon, as keywords in XPKeywords are separated by semicolons.

IMO, it's never worth dealing with XPKeywords. About the only thing that reads it is Windows and Windows will read XMP:Subject if it exists, making XPKeywords redundant.

QuoteMy general knowledge with coding is pretty limited, I get by with some basic bash scripts, but this code looks gibberish from my perspective xD (I guess this is Pearl language?).

Yep, it's Perl. Some of it is the ExifTool API.

I know some people hate ChatGPT, but it's often really good at breaking down code. For example, here's a breakdown of the part that writes XMP:Subject.

Quotebecause as per the documentation (Yes I'm trying to show off here xD) the XPKeywords is a tag within binary data? and can't be individually added/deleted.

XPKeywords is a simple string with the keywords separated by semicolons. It is treated as a single value where you would have to write code to add/subtract the keywords. With a list type tag, exiftool takes care of adding/subtracting things from the list for you. You would have to code this functionality separately.

QuoteCan you give me some hints how I could achieve this?

Honestly, the easiest thing would be to use this config to write to HierarchicalSubject and XMP:Subject (and IPTC:Keywords if desired) and then separately use this command to copy the data into XPKeywords
exiftool -sep ; "-XPKeywords<Subject" /path/to/files/[/quote]
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

KalyaSC

Heyha !

Thanks to both of you for your response.

Quote from: Phil Harvey on September 28, 2024, 04:31:13 PM3.  XPKeywords is not a list-type tag, so you would just write $val without splitting into a list:

                'EXIF:XPKeywords' => q{ $val },
- Phil

This will only add People|Family|Mary to the XPKeywords. I couldn't be that simple xD But thank you for your proposed solution, but as StarGeek pointed out:

QuoteIMO, it's never worth dealing with XPKeywords. About the only thing that reads it is Windows and Windows will read XMP:Subject if it exists, making XPKeywords redundant.

So I think I will follow his advice :) I didn't know Windows will read the XMP:Subject.



Quote from: StarGeek on September 28, 2024, 06:28:40 PMHonestly, the easiest thing would be to use this config to write to HierarchicalSubject and XMP:Subject (and IPTC:Keywords if desired) and then separately use this command to copy the data into XPKeywords
exiftool -sep ; "-XPKeywords<Subject" /path/to/files/

Thanks for the hint, but I think I will follow your advice not to bother with XPKeywords. Neither poking around with Pearl, it's way to different to what I'm acquainted with.

With both your answers, XMP:Subject being the globally accepted standard and Windows reading this field, I won't dig further the rabbit hole :).

Thanks !

StarGeek

Quote from: KalyaSC on September 29, 2024, 05:30:32 AMSo I think I will follow his advice :) I didn't know Windows will read the XMP:Subject.

See the Windows Metadata post for a list of what tags Windows reads to fill the Properties window.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype