exiftool-vendored.js - Delete all tags except specified (returns TypeError)

Started by beschler, March 28, 2024, 01:27:44 AM

Previous topic - Next topic

beschler

QUESTION

How can I use exiftool-vendored.js to delete all metadata tags on an image file except those specified?

USE CASE

I'm trying to remove all metadata on my file e.g. aperture, shutter speed, ISO, location, etc., but leave all information about copyright and author.

CODE

I have the following JS code:

const ExifTool = require("exiftool-vendored").ExifTool;

const exiftool = new ExifTool({
exiftoolArgs: [
`-all=`,
`-tagsFromFile`,
`@`,
`"-exif:Artist"`,
`"-exif:Copyright"`,
`"-exif:DateTimeOriginal"`,
`"-exif:OffsetTimeOriginal"`,
`"-iptc:Date Created"`,
`"-iptc:Time Created"`,
`"-iptc:By-line"`,
`"-iptc:By-line Title"`,
`"-iptc:Credit"`,
`"-iptc:Source"`,
`"-iptc:Copyright Notice"`,
`"-xmp:DateCreated"`,
`"-xmp:Source"`,
`"-xmp:Credit"`,
`"-xmp:AuthorsPosition"`,
`"-xmp:creator"`,
`"-xmp:rights"`,
`"-xmp:UsageTerms"`,
`"-xmp:CreatorContactInfo"`,
`"-xmp:WebStatement"`
]
});

(async () => {
const result = await exiftool.write("MY_IMAGE_FILE.jpg");
exiftool.end();
console.log( `result`, result );
})();

ERROR

When I execute this code...

node exiftool.js

...I receive the following error:

/Users/beschler/dev/metadata-test/node_modules/exiftool-vendored/dist/WriteTask.js:107
        if ((0, Number_1.isNumber)(tags.GPSLatitude)) {
                                        ^

TypeError: Cannot read properties of undefined (reading 'GPSLatitude')
    at WriteTask.for (/Users/beschler/dev/metadata-test/node_modules/exiftool-vendored/dist/WriteTask.js:107:41)
    at /Users/beschler/dev/metadata-test/node_modules/exiftool-vendored/dist/ExifTool.js:227:64
    at f (/Users/beschler/dev/metadata-test/node_modules/exiftool-vendored/dist/ExifTool.js:362:50)
    at async /Users/beschler/dev/metadata-test/exiftool.js:34:17

SYSTEM

exiftool-vendored: 25.0.0
node: 20.11.1
npm: 10.2.4

MacBook Pro, 16-inch, 2023
Apple M2 Pro
macOS Ventura 13.6.5



Thanks in advance for any assistance you can provide! Really appreciate all the hard work put into this project.

Phil Harvey

We are not associated with this JavaScript wrapper for ExifTool, and I have no experience using it.

Perhaps there is a discussion forum somewhere for exiftool-vendored.js?

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

Phil Harvey

...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

I know nothing about JS, but looking at your code, I see a FAQ #2/3 problem and possibly a FAQ #29, "My options don't work in a -@ ARGFILE" problem.

You are trying to write "iptc:Time Created" and "iptc:Date Created".  These are not tag names, they are tag descriptions (FAQ #2). Use the command in FAQ #3 to find the actual names of these tags.

If exiftool-vendored.js is creating a command line out of the the exiftoolArgs array, then there isn't a problem.  But if exiftool is running the the background through the -stay_open option, then the double quotes can't be there (FAQ #29).

No idea how you would get an error involving GPSLatitude as that doesn't even appear in your code.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

beschler

Totally understood.

Taking this question out of the context of exiftool-vendored.js, how would I achieve my goal? To clarify: I'm not trying to write any values in the tags I specified, I'm trying to delete all tags except those I specified.

My starting place (using exiftool itself, not the JS library) was this:

exiftool -all= -tagsFromFile @ "-exif:Artist" "-exif:Copyright" "-exif:DateTimeOriginal" "-exif:OffsetTimeOriginal" "-iptc:Date Created" "-iptc:Time Created" "-iptc:By-line" "-iptc:By-line Title" "-iptc:Credit" "-iptc:Source" "-iptc:Copyright Notice" "-xmp:DateCreated" "-xmp:Source" "-xmp:Credit" "-xmp:AuthorsPosition" "-xmp:creator" "-xmp:rights" "-xmp:UsageTerms" "-xmp:CreatorContactInfo" "-xmp:WebStatement" MY_IMAGE_FILE.jpg

Does this command do what I'm describing?

beschler

#5
I just ran this command using exiftool for Homebrew on Mac, and here was the result:

  • exif:ArtistKept
  • exif:CopyrightKept
  • exif:DateTimeOriginalKept
  • exif:OffsetTimeOriginalKept
  • iptc:Date CreatedDeleted
  • iptc:Time CreatedDeleted
  • iptc:By-lineKept
  • iptc:By-line TitleDeleted
  • iptc:CreditKept
  • iptc:SourceKept
  • iptc:Copyright NoticeDeleted
  • xmp:DateCreatedKept
  • xmp:SourceKept
  • xmp:CreditKept
  • xmp:AuthorsPositionKept
  • xmp:creatorKept
  • xmp:rightsKept
  • xmp:UsageTermsKept
  • xmp:CreatorContactInfoKept
  • xmp:WebStatementKept

UPDATE: I missed the recommendation above to review FAQ #s 2 and 3. I modified the following tag names in my command to remove spaces:

  • iptc:Date Creatediptc:DateCreated
  • iptc:Time Creatediptc:TimeCreated
  • iptc:By-line Titleiptc:By-lineTitle
  • iptc:Copyright Noticeiptc:CopyrightNotice

Then I modified my command as such:

exiftool -all= -tagsFromFile @ "-exif:Artist" "-exif:Copyright" "-exif:DateTimeOriginal" "-exif:OffsetTimeOriginal" "-iptc:DateCreated" "-iptc:TimeCreated" "-iptc:By-line" "-iptc:By-lineTitle" "-iptc:Credit" "-iptc:Source" "-iptc:CopyrightNotice" "-xmp:DateCreated" "-xmp:Source" "-xmp:Credit" "-xmp:AuthorsPosition" "-xmp:creator" "-xmp:rights" "-xmp:UsageTerms" "-xmp:CreatorContactInfo" "-xmp:WebStatement" 4--IMG_6715.jpg

And the output was almost perfect!

The only issues were the following:
  • iptc:TimeCreatedValue changed from 12:59:12 to 12:59:12-07:00 — it looks like it exiftool added my current timezone offset to the time block, but I'm not sure if my current timezone is the same as the timezone of when this photo was taken (esp. given daylight savings)
  • xmp:CreatorContactInfoValue changed from CreatorRegion: CA; CreatorWorkEmail: MY_EMAIL; CreatorCity: Los Angeles; CreatorWorkUrl: https://zachary.studio to CreatorCity: Los Angeles; CreatorRegion: CA; CreatorWorkEmail: MY_EMAIL; CreatorWorkUrl: https://zachary.studio — these values are effectively the same, just in different order, so this is not a big deal — just wondering why they were modified?

All this said, my question remains: is my approach the best way to achieve my goal? Ultimately, my desire is to not modify any existing tag values, only remove all tags that do not match my list.

Thanks so much everyone!

StarGeek

Quote from: beschler on March 28, 2024, 01:59:35 PMThe only issues were the following:
iptc:TimeCreatedValue changed from 12:59:12 to 12:59:12-07:00 — it looks like it exiftool added my current timezone offset to the time block, but I'm not sure if my current timezone is the same as the timezone of when this photo was taken (esp. given daylight savings)

Yes, the IPTC:TimeCreated requires a time zone and anything that doesn't include one is writing it incorrectly.

The IPTC time tags are not very good, IMO, as they separate the time and date.  EXIF date/time tags are usually the best place such data, following the corresponding XMP tags. EXIF tags do keep the time zone data in a separate tag, which makes it optional.  XMP tags are flexible and can include a time zone if desired, but it's not required.

Quotexmp:CreatorContactInfoValue changed from CreatorRegion: CA; CreatorWorkEmail: MY_EMAIL; CreatorCity: Los Angeles; CreatorWorkUrl: https://zachary.studio to CreatorCity: Los Angeles; CreatorRegion: CA; CreatorWorkEmail: MY_EMAIL; CreatorWorkUrl: https://zachary.studio — these values are effectively the same, just in different order, so this is not a big deal — just wondering why they were modified?

This would fall under FAQ #13 "Why is my file smaller after I use ExifTool to write information?". The data is the same, it's just written out to the file in a different order. Looks like it was sorted alphabetically, which I faintly recall Phil saying something about that in the past.

QuoteAll this said, my question remains: is my approach the best way to achieve my goal? Ultimately, my desire is to not modify any existing tag values, only remove all tags that do not match my list.

As long as the results are what you want, that is pretty much the way to go about it.

The only other suggestions I have are that EXIF is usually the best place for any time stamps, except XMP sidecar files, which can only hold XMP tags.

Also, I usually advise dropping IPTC tags unless something in your workflow absolutely requires them.  IPTC tags (which are different that IPTC Core/Ext tags, which are XMP) have character length limits which exiftool will enforce unless the -m (-ignoreMinorErrors) option is included. XMP is the newer standard and is much more flexible.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

beschler

I hear you, and I agree.

For context however, I'm operating under the understanding that the tag values are what they are at the start: my goal is not to modify any of the original tag values, even if they don't conform to whatever the latest standards are.

My goal is only to remove the tags not specified. In other words, write all tags except those specified to blank (delete them).

It sounds like what my command I shared is doing is:

  • Removing all tag values from the file, including the tags I specified.
  • Re-writing the original tag values back for the tags I specified, after they had all been written to blank values (deleted).

This seems to indicate why some of the tags I specified are different as a result.

My alternate approach is:

  • Loop through all tags (including tags that share the same name across different categories, e.g. iptc:Source and xmp:Source)
  • For each tag, if this tag name is found within the "keep" list, do not modify it
  • If this tag name is not found within the "keep" list, delete it

In order to accomplish this, I would need to know how to loop through each tag in this way. (One of the reasons why I was considering using the exiftool-vendored.js library.)

But keeping things in the context of the command line tool, does anyone here know of a way to accomplish my alternate approach?

StarGeek

I don't see any way to keep things exactly the same way. Any program that edits the metadata is going to change things.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).