lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.35k stars 1.3k forks source link

Keep only specified EXIF, IPTC, and XMP metadata tag values (similar to `withExifMerge`) #4033

Closed beschler closed 7 months ago

beschler commented 8 months ago

Question about an existing feature

The documentation states that the output option withExifMerge can be used to retain only the specified EXIF metadata from the input image into the output image. However, how can I also specify other metadata, for example IPTC and XMP tags?

(Output option keepMetadata indicates that EXIF, ICC, XMP, IPTC metadata can be retained - so this indicates these tags are accessible from within sharp.)

Additionally, I'm looking to retain the same values for the metadata tags specified, since they currently exist in the input file. (I'm not looking to manually specify override values.)

What are you trying to achieve?

I'm a photographer using Adobe Lightroom Classic and adding copyright information to my photographs. I would like to use sharp to optimize my photos for my website, and strip all metadata (e.g. aperture, shutter speed, etc.) from my images except retain metadata that relates to copyright information and original creation date. Specifically, I would like to remove all metadata except retain only the following fields:

When you searched for similar issues, what did you find that might be related?

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

(EXIF tags sourced from EXIF docs.)

const outputWithSelectMetadata = await sharp(inputWithExif)
  .withExifMerge({
    IFD0: {
      Artist: ORIGINAL_FROM_FILE, // how do I retain the original value?
      Copyright: ORIGINAL_FROM_FILE
    },
    ExifIFD: { // is this a valid EXIF tag group in sharp?
      DateTimeOriginal: ORIGINAL_FROM_FILE,
      OffsetTimeOriginal: ORIGINAL_FROM_FILE
    }
  })
  .withIPTCMerge({ // for example
    'Date Created': ORIGINAL_FROM_FILE,
    'Time Created': ORIGINAL_FROM_FILE,
    'By-line': ORIGINAL_FROM_FILE,
    'By-line Title': ORIGINAL_FROM_FILE,
    'Credit': ORIGINAL_FROM_FILE,
    'Source': ORIGINAL_FROM_FILE,
    'Copyright Notice': ORIGINAL_FROM_FILE
  })
  .withXMPMerge({ // for example
    'DateCreated': ORIGINAL_FROM_FILE,
    'Source': ORIGINAL_FROM_FILE,
    'Credit': ORIGINAL_FROM_FILE,
    'AuthorsPosition': ORIGINAL_FROM_FILE,
    'creator': ORIGINAL_FROM_FILE,
    'rights': ORIGINAL_FROM_FILE,
    'UsageTerms': ORIGINAL_FROM_FILE,
    'CreatorContactInfo': ORIGINAL_FROM_FILE,
    'WebStatement': ORIGINAL_FROM_FILE
  })
  .toFile('output.jpg', (err, info) => { ... });

Any help is appreciated! Thanks so much!

lovell commented 8 months ago

EXIF metadata support in sharp is provided via libvips+libexif, which only parses EXIF, therefore IPTC and XMP are exposed as binary blobs for parsing with external tools.

You might have some luck with the slightly-misnamed exiftool, which I believe can parse some IPTC and XMP metadata.

beschler commented 8 months ago

That's come up in my searches. I'll look there - thanks for the clarification!

lovell commented 7 months ago

I hope this information helped. Please feel free to re-open with more details if further assistance is required.