trying to update multiple tags with the same name

Started by gcx, November 02, 2015, 12:40:34 PM

Previous topic - Next topic

gcx

Hello people!

I'm very new to ExifTool, but I've already spent a few hours on a problem that I have, and I can't figure it out.

I have thousands of files that need to have some of their metadata updated, they're .psd files, to it's XMP metadata. Those files contain custom metadata, but many of the tags have the same name.
For instance, I've used ExifToop to retrieve a certain tag with the following command line:
exiftool(-k).exe -XMP-ns:LayerGroupsName -S -a -u -G1 -w! txt

I get this:
[XMP-ns] LayerGroupsName: [Surface]
[XMP-ns] LayerGroupsName: BaseColor
[XMP-ns] LayerGroupsName: Reflectance
[XMP-ns] LayerGroupsName: Roughness
[XMP-ns] LayerGroupsName: MetalMask
[XMP-ns] LayerGroupsName: Cavity
[XMP-ns] LayerGroupsName: Normal
[XMP-ns] LayerGroupsName: Work`

Now I'd like to update those tags, I've used this:
exiftool(-k).exe -XMP-ns:LayerGroupsName="something"

It does update, but only one of them:
[XMP-ns] LayerGroupsName: something

The other tags that were in XMP-ns are now in XMP-tmp0:
[XMP-tmp0] LayerGroupsName: [Surface]
[XMP-tmp0] LayerGroupsName: BaseColor
[XMP-tmp0] LayerGroupsName: Reflectance
[XMP-tmp0] LayerGroupsName: Roughness
[XMP-tmp0] LayerGroupsName: MetalMask
[XMP-tmp0] LayerGroupsName: Cavity
[XMP-tmp0] LayerGroupsName: Normal
[XMP-tmp0] LayerGroupsName: Work

How can I change ONE of those tags specifically, since they have the same name?
Is that an array of some sort? I have no idea how to edit it if it is.

BTW, I've had to make a custom config file, which is a total mess, so that may be the reason, but I have no idea what I must do. Here's the content of the config file:
#------------------------------------------------------------------------------
# File:         example.config
#
# Description:  Example user configuration file for Image::ExifTool
#
# Notes:        This example file shows how to define your own shortcuts and
#               add new EXIF, IPTC, XMP, PNG, MIE and Composite tags, as well
#               as how to specify preferred lenses for the LensID tag, and
#               define new file types and default ExifTool option values.
#
#               Note that unknown tags may be extracted even if they aren't
#               defined, but tags must be defined to be written.  Also note
#               that it is possible to override an existing tag definition
#               with a user-defined tag.
#
#               To activate this file, rename it to ".ExifTool_config" and
#               place it in your home directory or the exiftool application
#               directory.  (On Windows and Mac systems this must be done via
#               the command line since the GUI's don't allow filenames to begin
#               with a dot.  Use the "rename" command in Windows or "mv" on the
#               Mac.)  This causes ExifTool to automatically load the file when
#               run.  Your home directory is determined by the first defined of
#               the following environment variables:
#
#                   1.  EXIFTOOL_HOME
#                   2.  HOME
#                   3.  HOMEDRIVE + HOMEPATH
#                   4.  (the current directory)
#
#               Alternatively, the -config option of the exiftool application
#               may be used to load a specific configuration file (note that
#               this must be the first option on the command line):
#
#                   exiftool -config example.config ...
#
#               This example file defines the following 16 new tags as well as
#               a number of Shortcut and Composite tags:
#
#                   1.  EXIF:NewEXIFTag
#                   2.  GPS:GPSPitch
#                   3.  GPS:GPSRoll
#                   4.  IPTC:NewIPTCTag
#                   5.  XMP-xmp:NewXMPxmpTag
#                   6.  XMP-exif:GPSPitch
#                   7.  XMP-exif:GPSRoll
#                   8.  XMP-ns:NewXMPnsTag1
#                   9.  XMP-ns:NewXMPnsTag2
#                  10.  XMP-ns:NewXMPnsTag3
#                  11.  XMP-ns:NewXMPnsStruct
#                  12.  PNG:NewPngTag1
#                  13.  PNG:NewPngTag2
#                  14.  PNG:NewPngTag3
#                  15.  MIE-Meta:NewMieTag1
#                  16.  MIE-Test:NewMieTag2
#
#               For detailed information on the definition of tag tables and
#               tag information hashes, see lib/Image/ExifTool/README.
#------------------------------------------------------------------------------

# Shortcut tags are used when extracting information to simplify
# commonly used commands.  They can be used to represent groups
# of tags, or to provide an alias for a tag name.
%Image::ExifTool::UserDefined::Shortcuts = (
    MyShortcut => ['exif:createdate','exposuretime','aperture'],
    MyAlias => 'FocalLengthIn35mmFormat',
);

# NOTE: All tag names used in the following tables are case sensitive.

# The %Image::ExifTool::UserDefined hash defines new tags to be added
# to existing tables.
%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',
        },
        # add more user-defined EXIF tags here...
    },
    # the Geotag feature writes these additional GPS tags if available:
    'Image::ExifTool::GPS::Main' => {
        # Example 2.  GPS:GPSPitch
        0xd000 => {
            Name => 'GPSPitch',
            Writable => 'rational64s',
        },
        # Example 3.  GPS:GPSRoll
        0xd001 => {
            Name => 'GPSRoll',
            Writable => 'rational64s',
        },
    },
    # IPTC tags are added to a specific record type (eg. application record):
    # (Note: IPTC tag ID's are limited to the range 0-255)
    'Image::ExifTool::IPTC::ApplicationRecord' => {
        # Example 4.  IPTC:NewIPTCTag
        160 => {
            Name => 'NewIPTCTag',
            Format => 'string[0,16]',
        },
        # add more user-defined IPTC ApplicationRecord tags here...
    },
    # XMP tags may be added to existing namespaces:
    'Image::ExifTool::XMP::xmp' => {
        # Example 5.  XMP-xmp:NewXMPxmpTag
        NewXMPxmpTag => { Groups => { 2 => 'Author' } },
        LayerGroupsName => { Groups => { 2 => 'Author' } },
        # add more user-defined XMP-xmp tags here...
    },
    # special Geotag tags for XMP-exif:
    'Image::ExifTool::XMP::exif' => {
        # Example 6.  XMP-exif:GPSPitch
        GPSPitch => { Writable => 'rational', Groups => { 2 => 'Location' } },
        # Example 7.  XMP-exif:GPSRoll
        GPSRoll  => { Writable => 'rational', Groups => { 2 => 'Location' } },
    },
    # new XMP namespaces (eg. ns) must be added to the Main XMP table:
    'Image::ExifTool::XMP::Main' => {
        # namespace definition for examples 8 to 11
        ns => { # <-- must be the same as the NAMESPACE prefix
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::ns',
                # (see the definition of this table below)
            },
        },
        # add more user-defined XMP namespaces here...
    },
    # new PNG tags are added to the PNG::TextualData table:
    'Image::ExifTool::PNG::TextualData' => {
        # Example 12.  PNG:NewPngTag1
        NewPngTag1 => { },
        # Example 13.  PNG:NewPngTag2
        NewPngTag2 => { },
        # Example 14.  PNG:NewPngTag3
        NewPngTag3 => { },
    },
    # add a new MIE tag (NewMieTag1) and group (MIE-Test) to MIE-Meta
    # (Note: MIE group names must NOT end with a number)
    'Image::ExifTool::MIE::Meta' => {
        # Example 15.  MIE-Meta:NewMieTag1
        NewMieTag1 => {
            Writable => 'rational64u',
            Units => [ 'cm', 'in' ],
        },
        # new MIE "Test" group for example 16
        Test => {
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::MIETest',
                DirName => 'MIE-Test',
            },
        },
    },
    # Composite tags are added to the Composite table:
    'Image::ExifTool::Composite' => {
        # Composite tags are unique:  The Require/Desire elements specify
        # tags that must/may exist, and the keys of these hashes are used as
        # indices in the @val array of the ValueConv expression to access
        # the numerical (-n) values of these tags.  All Require'd tags must
        # exist for the Composite tag to be evaluated.  If no Require'd tags
        # are specified, then at least one of the Desire'd tags must exist.
        # See the Composite table in Image::ExifTool::Exif for more
        # examples, and lib/Image/ExifTool/README for all of the details.
        BaseName => {
            Require => {
                0 => 'FileName',
            },
            # remove the extension from FileName
            ValueConv => '$val[0] =~ /(.*)\./ ? $1 : $val[0]',
        },
        # the next few examples demonstrate simplifications which may be
        # used if only one tag is Require'd or Desire'd:
        # 1) the Require lookup may be replaced with a simple tag name
        # 2) "$val" may be used to represent "$val[0]" in the expression
        FileExtension => {
            Require => 'FileName',
            ValueConv => '$val=~/\.([^.]*)$/; $1',
        },
        # override CircleOfConfusion tag to use D/1750 instead of D/1440
        CircleOfConfusion => {
            Require => 'ScaleFactor35efl',
            Groups => { 2 => 'Camera' },
            ValueConv => 'sqrt(24*24+36*36) / ($val * 1750)',
            # an optional PrintConv may be used to format the value
            PrintConv => 'sprintf("%.3f mm",$val)',
        },
        # generate a description for this file type
        FileTypeDescription => {
            Require => 'FileType',
            ValueConv => 'GetFileType($val,1) || $val',
        },
        # calculate physical image size based on resolution
        PhysicalImageSize => {
            Require => {
                0 => 'ImageWidth',
                1 => 'ImageHeight',
                2 => 'XResolution',
                3 => 'YResolution',
                4 => 'ResolutionUnit',
            },
            ValueConv => '$val[0]/$val[2] . " " . $val[1]/$val[3]',
            # (the @prt array contains print-formatted values)
            PrintConv => 'sprintf("%.1fx%.1f $prt[4]", split(" ",$val))',
        },
        # [advanced] select largest JPEG preview image
        BigImage => {
            Groups => { 2 => 'Preview' },
            Desire => {
                0 => 'JpgFromRaw',
                1 => 'PreviewImage',
                2 => 'OtherImage',
                # (DNG and A100 ARW may be have 2 PreviewImage's)
                3 => 'PreviewImage (1)',
            },
            # ValueConv may also be a code reference
            # Inputs: 0) reference to list of values, 1) ExifTool object
            ValueConv => sub {
                my $val = shift;
                my ($image, $bigImage, $len, $bigLen);
                foreach $image (@$val) {
                    next unless ref $image eq 'SCALAR';
                    # check for JPEG image (or "Binary data" if -b not used)
                    next unless $$image =~ /^(\xff\xd8\xff|Binary data (\d+))/;
                    $len = $2 || length $$image; # get image length
                    # save largest image
                    next if defined $bigLen and $bigLen >= $len;
                    $bigLen = $len;
                    $bigImage = $image;
                }
                return $bigImage;
            },
        },
        # **** ADD ADDITIONAL COMPOSITE TAG DEFINITIONS HERE ****
    },
);

# This is a basic example of the definition for a new XMP namespace.
# This table is referenced through a SubDirectory tag definition
# in the %Image::ExifTool::UserDefined definition above.
# The namespace prefix for these tags is 'ns', which corresponds to
# an ExifTool family 1 group name of 'XMP-ns'.
%Image::ExifTool::UserDefined::ns = (
    GROUPS => { 0 => 'XMP', 1 => 'XMP-ns', 2 => 'Image' },
    NAMESPACE => { 'ns' => 'http://ns.myname.com/ns/1.0/' },
    WRITABLE => 'string',
    # Example 8.  XMP-ns:NewXMPnsTag1
    # - replace "NewXMPnsTag1" with your own tag name (eg. "MyTag")
    LayerGroupsName => { Writable => 'lang-alt' },
    # Example 9.  XMP-ns:NewXMPnsTag2
    NewXMPnsTag2 => { Groups => { 2 => 'Author' } },
    # Example 10.  XMP-ns:NewXMPnsTag3
    NewXMPnsTag3 => { List => 'Bag' },
    # Example 11.  XMP-ns:NewXMPnsStruct
    # - example structured XMP tag
    NewXMPnsStruct => {
        # the "Struct" entry defines the structure fields
        Struct => {
            # optional namespace prefix and URI for structure fields
            # (required only if different than NAMESPACE above)
            NAMESPACE => { 'test' => 'http://x.y.z/test/' },
            # optional structure name (used for warning messages only)
            STRUCT_NAME => 'MyStruct',
            # optional rdf:type property for the structure
            TYPE => 'http://x.y.z/test/xystruct',
            # structure fields (very similar to tag definitions)
            X => { Writable => 'integer' },
            Y => { Writable => 'integer' },
            # a nested structure...
            Things => {
                List => 'Bag',
                Struct => {
                    NAMESPACE => { thing => 'http://x.y.z/thing/' },
                    What  => { },
                    Where => { },
                },
            },
        },
        List => 'Seq', # structures may also be elements of a list
    },
    # Each field in the structure has an automatically-generated
    # corresponding flattened tag with an ID that is the concatenation
    # of the original structure tag ID and the field name (after
    # capitalizing the first letter of the field name if necessary).
    # The Name and/or Description of these flattened tags may be changed
    # if desired, but all other tag properties are taken from the
    # structure field definition.  When this is done, the "Flat" flag
    # must also be set in the tag definition.  For example:
    NewXMPnsStructX => { Name => 'SomeOtherName', Flat => 1 },
);

# Adding a new MIE group requires a few extra definitions
use Image::ExifTool::MIE;
%Image::ExifTool::UserDefined::MIETest = (
    %Image::ExifTool::MIE::tableDefaults,   # default MIE table entries
    GROUPS      => { 0 => 'MIE', 1 => 'MIE-Test', 2 => 'Document' },
    WRITE_GROUP => 'MIE-Test',
    # Example 16.  MIE-Test:NewMieTag2
    NewMieTag2  => { },     # new user-defined tag in MIE-Test group
);

# A special 'Lenses' list can be defined to give priority to specific lenses
# in the logic to determine a lens model for the Composite:LensID tag
@Image::ExifTool::UserDefined::Lenses = (
    'Sigma AF 10-20mm F4-5.6 EX DC',
    'Tokina AF193-2 19-35mm f/3.5-4.5',
);

# User-defined file types to recognize
%Image::ExifTool::UserDefined::FileTypes = (
    ns => { # <-- the extension of the new file type (case insensitive)
        # BaseType specifies the format upon which this file is based.
        # If BaseType is defined, then the file will be fully supported,
        # and in this case the Magic pattern should not be defined
        BaseType => 'TIFF',
        MIMEType => 'image/x-ns',
        Description => 'My ns file type',
    },
    YYY => {
        # without BaseType, the file will be recognized but not supported
        Magic => '0123abcd',    # regular expression to match at start of file
        MIMEType => 'application/test',
        Description => 'Test imaginary file type',
    },
    ZZZ => {
        # if neither BaseType nor Magic are defined, the file will be
        # recognized by extension only
        Description => 'My ZZZ file type',
    },
);

# Specify default ExifTool option values
# (see the Options function documentation for available options)
%Image::ExifTool::UserDefined::Options = (
    CoordFormat => '%.6f',  # change default GPS coordinate format
    Duplicates => 1,        # make -a default for the exiftool app
    GeoMaxHDOP => 4,        # ignore GPS fixes with HDOP > 4
);

#------------------------------------------------------------------------------
1;  #end

If someone has any idea on how to fix my problem, it would be hugely appreciated!  :)

Phil Harvey

I don't really understand what is going on here.

Unless your XMP tag is a List-type tag (bag, alt or seq), or is inside a structure inside a list, then it should only occur once.  But if it is a list, then reading FAQ 17 may help.

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

gcx

Thanks for your answer!

Yes, it appears to be a bag container, that's what I'm guessing from looking at the File Info in Photoshop:
         <ns:layerGroups>
            <rdf:Bag>
               <rdf:li rdf:parseType="Resource">
                  <xmpT:name>[Surface]</xmpT:name>

I've been through that FAQ point already, but in the case of a bag container, shouldn't the output be on one line, separated by commas?
The FAQ mentions lists, but I don't know what a bag is actually. Is it supposed to behave like a list?

I've tried something like this:
exiftool -keywords=one -keywords=two -keywords=three DIR

But it didn't work.

Phil Harvey

XMP has 3 types of lists (bag, alt and seq) that are all handled the same way as far as ExifTool is concerned.

But LayerGroups is a (bag) list of structures (hence the parsetype="Resource").  Reading and writing XMP structures is more complicated.  Add the -struct option to read them as structures, and write them in this format.  See this page for details about reading/writing structured XMP.

Also, your config file isn't defining the structure properly.  If you attach the entire XMP I will generate a config file for you that will write the structure.  (attach the output of "exiftool -xmp -b FILE > out.xmp".)

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

gcx

Wow, that's so nice of you!

This is the XMP that I got:

Quote<?xpacket begin='' id='W5M0MpC0ehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 10.04'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>

<rdf:Description rdf:about=''
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
  <dc:format>application/vnd.adobe.photoshop</dc:format>
</rdf:Description>

<rdf:Description rdf:about=''
  xmlns:ns='http://ns.myname.com/ns/1.0/'>
  <ns:LayerGroupsName>
   <rdf:Alt>
    <rdf:li xml:lang='x-default'>patate2</rdf:li>
   </rdf:Alt>
  </ns:LayerGroupsName>
</rdf:Description>

<rdf:Description rdf:about=''
  xmlns:photoshop='http://ns.adobe.com/photoshop/1.0/'>
  <photoshop:ColorMode>3</photoshop:ColorMode>
  <photoshop:DocumentAncestors>
   <rdf:Bag>
    <rdf:li>uuid:36440FC49481DC11A53F84F58E6BA9AD</rdf:li>
    <rdf:li>xmp.did:4AC8A968F8FFE411B439D4FED546DB51</rdf:li>
    <rdf:li>xmp.did:53C8A968F8FFE411B439D4FED546DB51</rdf:li>
    <rdf:li>xmp.did:BC185A8B9A00E511BDF1D501E7B80C6A</rdf:li>
   </rdf:Bag>
  </photoshop:DocumentAncestors>
  <photoshop:ICCProfile>sRGB IEC61966-2.1</photoshop:ICCProfile>
</rdf:Description>

<rdf:Description rdf:about=''
  xmlns:tmp0='http://potato.namespace/'
  xmlns:xmpT='http://ns.adobe.com/xap/1.0/t/'>
  <tmp0:layerGroups>
   <rdf:Bag>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:fileSuffix>S</xmpT:fileSuffix>
     <xmpT:name>[Surface]</xmpT:name>
     <xmpT:profileName>Surface</xmpT:profileName>
     <xmpT:profileOverride>false</xmpT:profileOverride>
     <xmpT:resizeOps>,2x platform3,2x platform4</xmpT:resizeOps>
     <xmpT:xmlRawData>&lt;settings profileid="10"&gt;&#xA;&#x9;&lt;resizeOp platform="platform1" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform2" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform3" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform4" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform0" operation="none" /&gt;&#xA;&lt;/settings&gt;&#xA;</xmpT:xmlRawData>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:fileSuffix>C</xmpT:fileSuffix>
     <xmpT:name>BaseColor</xmpT:name>
     <xmpT:profileName>Base Color</xmpT:profileName>
     <xmpT:profileOverride>false</xmpT:profileOverride>
     <xmpT:resizeOps>,2x platform3,2x platform4</xmpT:resizeOps>
     <xmpT:xmlRawData>&lt;settings profileid="5"&gt;&#xA;&#x9;&lt;resizeOp platform="platform1" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform2" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform3" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform4" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform0" operation="none" /&gt;&#xA;&lt;/settings&gt;&#xA;</xmpT:xmlRawData>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:name>Reflectance</xmpT:name>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:name>Roughness</xmpT:name>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:name>MetalMask</xmpT:name>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:name>Cavity</xmpT:name>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:fileSuffix>N</xmpT:fileSuffix>
     <xmpT:name>Normal</xmpT:name>
     <xmpT:profileName>Normal</xmpT:profileName>
     <xmpT:profileOverride>false</xmpT:profileOverride>
     <xmpT:resizeOps>,2x platform3,2x platform4</xmpT:resizeOps>
     <xmpT:xmlRawData>&lt;settings profileid="6"&gt;&#xA;&#x9;&lt;resizeOp platform="platform1" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform2" operation="none" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform3" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform4" operation="scale" value="2" /&gt;&#xA;&#x9;&lt;resizeOp platform="platform0" operation="none" /&gt;&#xA;&lt;/settings&gt;&#xA;</xmpT:xmlRawData>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <xmpT:name>Work</xmpT:name>
    </rdf:li>
   </rdf:Bag>
  </tmp0:layerGroups>
</rdf:Description>

<rdf:Description rdf:about=''
  xmlns:xmp='http://ns.adobe.com/xap/1.0/'>
  <xmp:CreateDate>2015-05-21T16:55:31-04:00</xmp:CreateDate>
  <xmp:CreatorTool>Adobe Photoshop CS6 (Windows)</xmp:CreatorTool>
  <xmp:MetadataDate>2015-10-01T11:26:04-04:00</xmp:MetadataDate>
  <xmp:ModifyDate>2015-10-01T11:26:04-04:00</xmp:ModifyDate>
</rdf:Description>

<rdf:Description rdf:about=''
  xmlns:stEvt='http://ns.adobe.com/xap/1.0/sType/ResourceEvent#'
  xmlns:xmpMM='http://ns.adobe.com/xap/1.0/mm/'>
  <xmpMM:DocumentID>xmp.did:53C8A968F8FFE411B439D4FED546DB51</xmpMM:DocumentID>
  <xmpMM:History>
   <rdf:Seq>
    <rdf:li rdf:parseType='Resource'>
     <stEvt:action>created</stEvt:action>
     <stEvt:instanceID>xmp.iid:53C8A968F8FFE411B439D4FED546DB51</stEvt:instanceID>
     <stEvt:softwareAgent>Adobe Photoshop CS6 (Windows)</stEvt:softwareAgent>
     <stEvt:when>2015-05-21T16:55:31-04:00</stEvt:when>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <stEvt:action>saved</stEvt:action>
     <stEvt:changed>/</stEvt:changed>
     <stEvt:instanceID>xmp.iid:1BDBB8C0FBFFE411B439D4FED546DB51</stEvt:instanceID>
     <stEvt:softwareAgent>Adobe Photoshop CS6 (Windows)</stEvt:softwareAgent>
     <stEvt:when>2015-05-21T17:03:03-04:00</stEvt:when>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <stEvt:action>saved</stEvt:action>
     <stEvt:changed>/</stEvt:changed>
     <stEvt:instanceID>xmp.iid:400A52F64968E5119F58D0AF8963D36B</stEvt:instanceID>
     <stEvt:softwareAgent>Adobe Photoshop CS6 (Windows)</stEvt:softwareAgent>
     <stEvt:when>2015-10-01T11:26:04-04:00</stEvt:when>
    </rdf:li>
   </rdf:Seq>
  </xmpMM:History>
  <xmpMM:InstanceID>xmp.iid:400A52F64968E5119F58D0AF8963D36B</xmpMM:InstanceID>
  <xmpMM:OriginalDocumentID>xmp.did:53C8A968F8FFE411B439D4FED546DB51</xmpMM:OriginalDocumentID>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
                                                                                                   
<?xpacket end='w'?>

Phil Harvey

#5
OK, attached is a config file that should do what you want.  Add "-config LayerGroups.config" as the first option in your command to load this config file (from the current directory).

- Phil

Edit: Fixed case of "layerGroups" tag ID
...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 ($).

gcx

I've made some progress, but I'm afraid that I'm still not able to write it...

Using your config file as well as adding -struct to the command line, I get this:
QuoteLayerGroups: [{FileSuffix=S,Name=|[Surface],ProfileName=Surface,ProfileOverride=false,ResizeOps=|,2x platform3|,2x platform4,XmlRawData=<settings profileid="10">..<resizeOp platform="platform1" operation="none" />..<resizeOp platform="platform2" operation="none" />..<resizeOp platform="platform3" operation="scale" value="2" />..<resizeOp platform="platform4" operation="scale" value="2" />..<resizeOp platform="platform0" operation="none" />.</settings>.},{FileSuffix=C,Name=BaseColor,ProfileName=Base Color,ProfileOverride=false,ResizeOps=|,2x platform3|,2x platform4,XmlRawData=<settings profileid="5">..<resizeOp platform="platform1" operation="none" />..<resizeOp platform="platform2" operation="none" />..<resizeOp platform="platform3" operation="scale" value="2" />..<resizeOp platform="platform4" operation="scale" value="2" />..<resizeOp platform="platform0" operation="none" />.</settings>.},{Name=Reflectance},{Name=Roughness},{Name=MetalMask},{Name=Cavity},{FileSuffix=N,Name=Normal,ProfileName=Normal,ProfileOverride=false,ResizeOps=|,2x platform3|,2x platform4,XmlRawData=<settings profileid="6">..<resizeOp platform="platform1" operation="none" />..<resizeOp platform="platform2" operation="none" />..<resizeOp platform="platform3" operation="scale" value="2" />..<resizeOp platform="platform4" operation="scale" value="2" />..<resizeOp platform="platform0" operation="none" />.</settings>.},{Name=Work}]

I used what's between the brackets [] as the value to update for LayerGroup, so like this:
exiftool(-k) -yourconfigfile -XMP:LayerGroups=(what's between the brackets but with some changes) myfile.psd
I get this:
Quote1 output files created
Warning: [minor] Fixed incorrect tag ID case for XMP-ns:LayerGroups - myfile.psd
    1 image files updated

But it didn't update properly. The new file is 12 KB smaller though, and the XMP inside of Photoshop is broken (things moved around and the data is not readable anymore in my custome photoshop tool).  :'(

Phil Harvey

The problem is in the quoting of the complex command-line argument.  To avoid this problem, I would suggest:

1. exiftool -layergroups -struct -b SRCFILE > out.txt

2. exiftool -config LayerGroups.config "-layergroups<=out.txt" DSTFILE

Also, I have updated the config file attached to my previous post to fix the incorrect tag ID case.

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

gcx

That worked perfectly!

Thanks a lot for your help, you have no idea how much time your help and your tool are saving me!!!