Read GPSAltitude without its reference tag; keep unnamed EXIF tags
check / check (push) Successful in 1m25s
check / check (push) Successful in 1m25s
exif() takes the altitude from the GPSAltitude tag and negates it only when GPSAltitudeRef is 1, so a file with GPSAltitude and no GPSAltitudeRef keeps its altitude, above sea level. A test covers that file. backup-metadata --exif keeps the EXIF tags exifreader has no name for. The comments in src/exif.ts say the thumbnail's tags are not kept and that a tag with several values computes to an array. Model: opus-5-5
This commit is contained in:
+14
-4
@@ -1,7 +1,7 @@
|
||||
// EXIF in an original's bytes, read with exifreader, which reads it from JPEG,
|
||||
// HEIC/HEIF, AVIF, PNG, WebP and the other image formats it supports.
|
||||
// `backup-metadata --exif` records every EXIF tag it finds; `Photo.exif()`
|
||||
// returns the common fields picked from them here.
|
||||
// `backup-metadata --exif` records every EXIF tag it finds except the
|
||||
// thumbnail's; `Photo.exif()` returns the common fields picked from them here.
|
||||
|
||||
import ExifReader, { type ExpandedTags } from "exifreader";
|
||||
|
||||
@@ -9,7 +9,11 @@ import ExifReader, { type ExpandedTags } from "exifreader";
|
||||
// them (`gps`), and where the EXIF block lies in `bytes` (`metadataRange`).
|
||||
// Undefined when exifreader cannot read the file at all, such as a video. An
|
||||
// EXIF block it finds but reads no tag from comes back as an empty `exif`.
|
||||
// Each tag's `computed` holds its value as a plain string or number.
|
||||
// `exif` holds every tag except the thumbnail's; a tag exifreader has no name
|
||||
// for is keyed `undefined-<tag number>`. Each tag's `computed` holds its value
|
||||
// as a string or number, or as an array of them for a tag with several values,
|
||||
// such as `GPSLatitude`'s `[40, 26, 46]`. A fraction with a zero denominator
|
||||
// computes to null.
|
||||
export const readExifTags = (bytes: Uint8Array): ExpandedTags | undefined => {
|
||||
try {
|
||||
return ExifReader.loadView(
|
||||
@@ -18,6 +22,7 @@ export const readExifTags = (bytes: Uint8Array): ExpandedTags | undefined => {
|
||||
expanded: true,
|
||||
computed: true,
|
||||
includeOffsets: true,
|
||||
includeUnknown: true,
|
||||
includeTags: { exif: true, gps: true },
|
||||
},
|
||||
);
|
||||
@@ -77,6 +82,7 @@ export const readPhotoExif = (bytes: Uint8Array): PhotoExif => {
|
||||
const tags = readExifTags(bytes);
|
||||
const exif = tags?.exif;
|
||||
const gps = tags?.gps;
|
||||
const altitude = asNumber(exif?.GPSAltitude?.computed);
|
||||
const fields: PhotoExif = {
|
||||
make: asString(exif?.Make?.computed),
|
||||
model: asString(exif?.Model?.computed),
|
||||
@@ -91,7 +97,11 @@ export const readPhotoExif = (bytes: Uint8Array): PhotoExif => {
|
||||
orientation: asNumber(exif?.Orientation?.computed),
|
||||
gpsLatitude: asNumber(gps?.Latitude),
|
||||
gpsLongitude: asNumber(gps?.Longitude),
|
||||
gpsAltitude: asNumber(gps?.Altitude),
|
||||
// A GPSAltitudeRef of 1 means the altitude is below sea level.
|
||||
gpsAltitude:
|
||||
altitude !== undefined && exif?.GPSAltitudeRef?.value === 1
|
||||
? -altitude
|
||||
: altitude,
|
||||
};
|
||||
// Leave out what the file lacks, so a missing field is absent rather than
|
||||
// present and undefined.
|
||||
|
||||
Reference in New Issue
Block a user