I'm copying metadata from A to B, where B is a resized (smaller) version of A.
Depending on the user's settings, EXIF and/or XMP data is copied. Since B is a smaller version of A, I try to correct tags related to image dimensions on-the-fly when copying the metadata (and also update some other tags, like instanceId).
My general approach in the ARGS file is:
-tagsfromfile
A.jpg
-XMP:all
-XMP-xmp:ModifyDate<Now
-XMP-xmp:CreateDate<Now
...
And to update/correct some tags:
-TagsFromFile
@
-icc_profile
-ThumbnailImage=
-PreviewImage=
-XMP-tiff:ImageHeight<ImageHeight
-if '$XMP-tiff:ImageHeight'
-XMP-tiff:ImageWidth<ImageWidth
-if '$XMP-tiff:ImageWidth'
-XMP-exif:ExifImageHeight<ImageHeight
-if '$XMP-exif:ExifImageHeight'
-XMP-exif:ExifImageWidth<ImageWidth
-if '$XMP-exif:ExifImageWidth'
B.jpg
Since I don't know if the output image has XMP, I use -if conditions. And this appears to work great.
But it does not work for XMP RegionInfo as it seems. Because adding
-xmp-mwg-rs:RegionAppliedToDimensionsH<ImageHeight
-if '$xmp-mwg-rs:RegionAppliedToDimensionsH'
-xmp-mwg-rs:RegionAppliedToDimensionsW<ImageWidth
-if '$xmp-mwg-rs:RegionAppliedToDimensionsW'
seems to have no effect. The RegionInfo in the B.jpg still has the (now wrong) dimensions of the A.jpg file.
Running the args file with the -v2 option added, I see this:
+ XMP-mwg-rs:RegionAppliedToDimensionsH = '834'
+ XMP-mwg-rs:RegionAppliedToDimensionsW = '1280'
- XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:h = '834'
- XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:w = '1280'
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:h = '1960.000000'
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:unit = 'pixel'
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:w = '3008.000000'
So ExifTool seems to set the info (+), remove it (-) and then set it again from the A original file?
This is a bit tricky. ExifTool copies as structures by default, so what you are seeing here:
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:h = '1960.000000'
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:unit = 'pixel'
+ XMP-mwg-rs:Regions/mwg-rs:AppliedToDimensions/stDim:w = '3008.000000'
is the XMP-mwg-rs:RegionInfo structure being copied. There are various work-arounds if you want to copy this and change the w/h dimensions. Maybe the easiest thing is to write the w/h in a subsequent command.
I assume that you already have multiple command executions (-execute), because otherwise your -if conditions wouldn't act on the individual tags.
- Phil
Hi, Phil
I try to avoid superfluous -executes where possible because many of the files I deal with are big and on slow network storage.
If you say it's not possible otherwise, I will move this into a separate -execute cycle.
Quotebecause otherwise your -if conditions wouldn't act on the individual tags.
Not sure that I get this? Can I don't do conditionals per tag using separate -if statements?
I want to update several tags, but only if they already exist in the target file.
Quote from: Mac2 on October 12, 2014, 07:12:00 AM
I try to avoid superfluous -executes where possible because many of the files I deal with are big and on slow network storage.
Understandable. Let me think about this. The alternatives I had in mind aren't very satisfying because they involve copying as flattened tags, which would have the potential of mixing up the original structure.
QuoteCan I don't do conditionals per tag using separate -if statements?
I want to update several tags, but only if they already exist in the target file.
The
-if condition is used to decide whether or not to process the file, so it doesn't do what you want. Instead, use the
-wm w if you just want to update existing tags.
- Phil
OK. Here goes.
Your problem with the XMP-mwg-rs regions was due to writing a mix of structured and flattened tags (and the order of operations in this case is not as expected). As I said, writing only flattened tags (by adding --struct) has its drawbacks. So the challenge then is how to modify the RegionInfo structure so it is updated to contain the new image dimensions. For this, the advanced formatting expression (along with some knowledge of ExifTool internals) comes to the rescue:
-regioninfo<${regioninfo;s/\bW=\d+/W=$$self{VALUE}{ImageWidth}/;s/\bH=\d+/H=$$self{VALUE}{ImageHeight}/}
Here I replace the W and H of the RegionInfo structure with the values directly from the ExifTool object's VALUE lookup. This is not something I would normally recommend, but in this instance I can't see a better alternative.
- Phil
Edit: Re the order-of-operations problem. I think it may be wise to change ExifTool to always allow flattened tags to override structures when writing. It didn't happen in this case for a technical reason, but I am looking into changing this. If successful then this problem may be solved in version 9.73.
Edit2: OK. So my smart work-around using the advanced formatting expression above will be moot. ExifTool 9.73 (which I hope to release tomorrow) will fix the order of operations so that flattened tags may always be be used to replace elements in a structure when writing a mix of structured and flattened tags.
Hah! I knew this was a tricky one. Thanks for spending the time to figure this all out. Structured tags are the common metadata mess, with some icing on top... ;D
For now, I have settled to deal with this in my code to make it work in all cases. I've came up with a bunch of another special cases and these are beyond ExifTool to handle.
When the output file contains XMP data, I do a second write, fixing the image dimension related tags. Same for standard EXIF data if it is copied.
If the XMP copied also contains region info, I fix the applied-to dimensions in the second write operation as well.
If the image dimensions are the same (can happen), nothing needs to be done at all.
Sounds good.
In general, complex logic like this can be handled easily by a custom script via the ExifTool API -- the application just can't provide the infinite flexibility that a custom script can.
- Phil