Defining tags not already in a group

Started by remarkableearth, November 14, 2017, 07:29:06 PM

Previous topic - Next topic

remarkableearth

I'd like to customize a set of tag/value pairs for a set of images (1000's). I follow the ExifTool FAQ example on "my user-defined tags don't work" just fine and get the expected result for defining a new tag into the XMP Group. In the example,
-NewXMPxmpTag=test is used to define a new tag name of "NewXMPxmpTag" whose value is "test." It is placed into the group "XMP," if I understand things correctly.

So how do I define my own new tags without a group? That is, because I'm defining the name of the tag they don't already belong to a group, so what group do I call out such as the example above calls out the XMP group?

Here is what I'm attempting: I'd like to define my own tag/value pairs as ABC=xxx, DEF=yyy, GHI=zzz. The group is inconsequential to me.

(And once I solve this problem I'd like to make a shortcut to perform the writing as a shorter script.)


Phil Harvey

The "XMP" group is the location where the metadata is stored.  It must be stored somewhere in the file.  For a JPEG file your only real choices are XMP, IPTC or EXIF.  XMP is the most flexible, so I would recommend 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 ($).

remarkableearth

Thanks, Phil.

A related question:
If I have about 20 new tags to add and you recommend I add them to the XMP group, do I add them using:
%Image::ExifTool::UserDefined = (
    # All EXIF tags are added to the Main table, and WriteGroup is used to
    # specify where the tag is written (default is ExifIFD if not specified):
    'Image::ExifTool::Exif::Main' => {
        # Example 1.  EXIF:NewEXIFTag
        0xd000 => {
            Name => 'NewEXIFTag',
            Writable => 'int16u',
            WriteGroup => 'IFD0',
        }

substituting XMP for Exif in 'Image::ExifTool::Exif::Main' => { and then, of course, modifying the remainder for my custom info.

Or do I add them using
# XMP tags may be added to existing namespaces:
    'Image::ExifTool::XMP::xmp' => {
        # Example 5.  XMP-xmp:NewXMPxmpTag
        NewXMPxmpTag => { Groups => { 2 => 'Author' } },
        # add more user-defined XMP-xmp tags here...
    }

substituting my custom tag for NewXMPxmpTag (for each of the 20 tags).

If you recommend the first bit of code, I understand what to do with each of the parts. If it's the second bit, I don't understand how to modify the { Groups => { 2 => 'Author' } } part.

Please advise.

Matt

Phil Harvey

You can't just substitute EXIF with XMP in the config file.  Start from the original example and look at the XMP-xxx example tags.  Follow this example, and replace "xxx" with your own XMP namespace prefix.  I don't  think you should use an existing namespace.

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

remarkableearth

Thanks, Phil.

I'd like to create the new namespace 'testnamespace', create the tag 'testtag' within it, and populate it with 'testvalue'. Here is what I've done:

In the config file I replaced "xxx" with my namespace "testnamespace":
    'Image::ExifTool::XMP::Main' => {
        # namespace definition for examples 8 to 11
        testnamespace => { # <-- must be the same as the NAMESPACE prefix
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::testnamespace',
                # (see the definition of this table below)
            },
        },


And I added testtag => {}, to the section # XMP tags may be added to existing namespaces:
    'Image::ExifTool::XMP::xmp' => {
        # Example 5.  XMP-xmp:NewXMPxmpTag
        NewXMPxmpTag => { Groups => { 2 => 'Author' } },
        # add more user-defined XMP-xmp tags here...
        testtag => {},
    },


Then at the command line I entered exiftool -testnamespace:testtag+=testvalue IMG_1546.JPG to add the testvalue to testtag and got Warning: Tag 'testnamespace:Testtag' is not defined

What am I doing wrong? I thought I had defined testtag, but apparently not.

Phil Harvey

I think you are confused by all the other examples in the sample config file.  Here is the basics, with all the other stuff removed:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::Main' => {
        xxx => { # <-- must be the same as the NAMESPACE prefix
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::xxx',
                # (see the definition of this table below)
            },
        },
    },
);

%Image::ExifTool::UserDefined::xxx = (
    GROUPS        => { 0 => 'XMP', 1 => 'XMP-xxx', 2 => 'Image' },
    NAMESPACE     => { 'xxx' => 'http://ns.myname.com/xxx/1.0/' },
    WRITABLE      => 'string', # (default to string-type tags)
    NewXMPxxxTag1 => { },
);

1;  #end


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

remarkableearth

Phil,

Thank you. Indeed, I was a bit confused. So here is what I took from you, edited for my variable names:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::Main' => {
        testnamespace => { # <-- must be the same as the NAMESPACE prefix
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::testnamespace',
                # (see the definition of this table below)
            },
        },
    },
);

%Image::ExifTool::UserDefined::testnamespace = (
    GROUPS        => { 0 => 'XMP', 1 => 'XMP-testnamespace', 2 => 'Image' },
    NAMESPACE     => { 'testnamespace' => 'http://ns.myname.com/testnamespace/1.0/' },
    WRITABLE      => 'string', # (default to string-type tags)
    testtag => { },
);

1;  #end


Then I execute at the command line exiftool -testnamespace:testtag+=testvalue IMG_1546.JPG and received Warning: Tag 'testnamespace:testtag' is not defined in return. Didn't I define it?

I get the same result when I capitalize the leading 't' for each of my variables (to follow the pattern in the config file.

I would appreciate whatever advice you may offer.

Phil Harvey

"testnamespace" is the XMP namespace prefix.

The corresponding ExifTool group name is "XMP-testnamespace" (see the GROUPS definition in your config file).  So try this:

exiftool -xmp-testnamespace:testtag=testvalue IMG_1546.JPG

or just

exiftool -testtag=testvalue IMG_1546.JPG

Note I have also removed the "+" in "+=" because you aren't adding to anything (and the tag isn't a list-type tag anyway).

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

remarkableearth

Thanks for the clarification of the distinction between the namespace prefix and group name. As soon as I read it, I realized that.

As for your advice, the shorter line of code worked (thank you very much) but the longer one specifying the group name returned Warning: Tag 'xmp-testnamespace:Testtag' is not defined

By the way, do capital letters matter when defining or calling the various variables? I notice leading capitals within the config file and printing of tags and values but commands use lower case without problems.

Phil Harvey

Capitals don't matter.  This command works fine for me with the config file you posted:

> exiftool -xmp-testnamespace:testtag=testvalue a.jpg
    1 image files updated


If the tag isn't defined, then the config file may not be loading.  In this case, see FAQ 11.  But you say it works for the shorter command, so the config must be loading.  In this case you are using a different config file or a different command from me, and something is spelled wrong somewhere.

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

remarkableearth

Thank you so very much, Phil.

I checked my syntax and spelling of the code that worked for you but not for me and see no difference, so that's a little confusing. I certainly prefer fewer keystrokes of the shorter command, but specifying the group is helpful to avoid mistakes.

-Matt