photostructure / exiftool-vendored.js

Fast, cross-platform Node.js access to ExifTool
https://photostructure.github.io/exiftool-vendored.js/
MIT License
405 stars 37 forks source link

Delete all tags except specified (returns `TypeError`) #178

Closed beschler closed 3 months ago

beschler commented 3 months ago

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.

mceachen commented 3 months ago

You've got several issues going on:

  1. You're giving the options to the wrong thing. Don't give the ExifTool constructor the array: give the .deleteAllTags function the array.
  2. That isn't the correct syntax for ExifTool, in any event. As ExifTool's API for tag retention is a bit wacky, rather than having you grok the -TAGNAME<TAGNAME syntax, I've just added a new retain argument to ExifTool.deleteAllTags: feed it an array of tag names you want to retain. This will be in version 25.1.0.
  3. You've got some spaces in those tag names--that won't work. ExifTool tagnames are case-insensitive, but not whitespace-insensitive.

So:

import {exiftool} from "exiftool-vendored"

async function run() {
  await exiftool.deleteAllTags(
    "MY_IMAGE_FILE.jpg", 
    { retain: ["Artist", "Copyright","DateTimeOriginal", /* and all the others you've got */] }
  )
  await exiftool.end()
}

There are several new tests so you can see it in action in WriteTask.spec.ts.

beschler commented 3 months ago

@mceachen, this is awesome!

Thank you so much for doing this. I will update my NPM package to download the new version which supports this retain option, and give this a go.

I really appreciate your help with this 🙏🏻

mceachen commented 3 months ago

Just FYI, there were a couple hangups with the release: GitHub Actions boxes didn't behave like my local test machines, so there's been some shenanigans in getting this out the door. It'll happen today.

mceachen commented 3 months ago

Released!

beschler commented 3 months ago

Thank you so much @mceachen!

I see the new release in GitHub and NPM. I updated my package successfully to 25.1.0.

npm install exiftool-vendored@latest

I updated my code per your recommendation, and it worked perfectly!

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

async function run() {
    await exiftool.deleteAllTags(
        "6--IMG_6715.jpg", 
        {
            retain: [
                "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"
            ]
        }
    );
    await exiftool.end();
    console.log( `SUCCESS!` );
}

run();

I can't thank you enough. I can now push forward with my project. (I made sure to give this repo a star.) Cheers! 🍻