Skip to content

Add/Preserve/Modify EXIF Metadata For Images #10016

@solonovamax

Description

@solonovamax

🙋 Feature Request

The ability to add/preserve/modify EXIF metadata & ICC profile for images could be a useful feature.

😯 Current Behavior

Currently, there is some support for retaining EXIF metadata, however it is not configurable, and from what I can tell it does not preserve it when building for production:

it('should retain EXIF data', async () => {
const b = await bundle(
path.join(__dirname, '/integration/image-exif/resized.html'),
);
const imagePath = b.getBundles().find(b => b.type === 'jpeg').filePath;
const buffer = await outputFS.readFile(imagePath);
const image = await sharp(buffer).metadata();
const exif = exifReader(image.exif);
assert.strictEqual(
exif.Photo.UserComment.toString(),
'ASCII\u0000\u0000\u0000This is a comment',
);
});
it('should remove EXIF data when optimizing', async () => {
const b = await bundle(
path.join(__dirname, '/integration/image-exif/resized.html'),
{
defaultTargetOptions: {
shouldOptimize: true,
},
},
);
const imagePath = b.getBundles().find(b => b.type === 'jpeg').filePath;
const buffer = await outputFS.readFile(imagePath);
const image = await sharp(buffer).metadata();
assert.strictEqual(image.exif, undefined);
});

However, I'm unsure about this.

There is no support for retaining the ICC profile. Currently, it will convert images to a "web-friendly sRGB ICC profile":

withMetadata

withMetadata([options]) ⇒ Sharp

Keep most metadata (EXIF, XMP, IPTC) from the input image in the output image.

This will also convert to and add a web-friendly sRGB ICC profile if appropriate.

💁 Possible Solution

It would be nice if there was a way to do this using image transformations.

For example:

<img src="image.jpg?metadata=true"> <!-- preserve all metadata -->
<img src="image.jpg?metadata=false"> <!-- strip all metadata -->
<img src="image.jpg"> <!-- strip metadata by default, unless configured otherwise. where could this config be located? -->

<img src="image.jpg?exif=true"> <!-- preserve exif -->
<img src="image.jpg?metadata=false&exif=true"> <!-- strip all metadata except exif -->
<img src="image.jpg?metadata=true&exif=false"> <!-- preserve all metadata except exif -->

<img src="image.jpg?icc=preserve"> <!-- preserves ICC profile -->
<img src="image.jpg?icc=srgb"> <!-- convert to named ICC profile -->
<img src="image.jpg"> <!-- convert to a "web-friendly sRGB ICC profile" (current behaviour) -->

TODO: How should adding new metadata be handled? A possible solution could be something like

<!--
This preserves the existing EXIF (exif=true) and adds/overwrites the following EXIF tags:
- the "Copyright" tag with the value "(c) Me and Myself"
- the "Photographer" tag with the value "Me"

To not preserve the existing EXIF and only add the new tags, remove `exif=true`.
-->
<img src="image.jpg?exif=true&exif={Image.Copyright=(c) Me and Myself,Photo.Photographer=Me}">

For a list of EXIF tag names, see:

This part needs to be investigated further.

🔦 Context

See:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions