[web] Parse description from image metadata

- Implements https://github.com/ente-io/ente/discussions/3857#discussioncomment-11764990
- Tested on the samples provided therein.
This commit is contained in:
Manav Rathi
2025-01-08 07:15:17 +05:30
parent ead2b3d3d6
commit f6ca19babc
4 changed files with 31 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
## v1.7.8 (Unreleased)
- Parse description from image metadata.
- .
## v1.7.7

View File

@@ -1073,7 +1073,8 @@ const extractImageOrVideoMetadata = async (
if (h) publicMagicMetadata.h = ensureInteger(h);
}
const caption = parsedMetadataJSON?.description;
const caption =
parsedMetadataJSON?.description ?? parsedMetadata.description;
if (caption) {
publicMagicMetadata.caption = caption;
}

View File

@@ -604,6 +604,10 @@ export interface ParsedMetadata {
creationDate?: ParsedMetadataDate;
/** The GPS coordinates where the photo was taken. */
location?: Location;
/**
* A caption / description attached by the user to the photo.
*/
description?: string;
}
/**

View File

@@ -40,10 +40,12 @@ export const parseExif = (tags: RawExifTags) => {
const location = parseLocation(tags);
const creationDate = parseCreationDate(tags);
const dimensions = parseDimensions(tags);
const description = parseDescription(tags);
const metadata: ParsedMetadata = dimensions ?? {};
if (creationDate) metadata.creationDate = creationDate;
if (location) metadata.location = location;
if (description) metadata.description = description;
return metadata;
};
@@ -536,3 +538,25 @@ export const tagNumericValue = (
const v = tag.value;
return Array.isArray(v) ? (v[0] ?? 0) / (v[1] ?? 1) : v;
};
/**
* Parse the description for an image from the metadata embedded in the file.
*
* This function will read the description from the following fields, in order:
*
* 1. XMP-dc:description
* 2. IPTC | Caption/Abstract (120)
* 3. EXIF IFD0 | 0x010e | ImageDescription
*
* For an overview of why this ordering was chosen, see
* https://github.com/ente-io/ente/discussions/3857#discussioncomment-11764990
*/
const parseDescription = (tags: RawExifTags) =>
// While the TypeScript tags for these three fields are varying (The XMP one
// doesn't have a static type, the IPTC one is marked as a number array, and
// the Exif one is a string array), for all three of these, the ExifReader
// description property (not related to the image "description" in the sense
// of this function) holds the singular string we're interested in.
tags.xmp?.description?.description ??
tags.iptc?.["Caption/Abstract"]?.description ??
tags.exif?.ImageDescription?.description;