Photo: one async method per EXIF field (closes #148)

Thirteen methods on Photo, make() through gpsAltitude(), each named after
its PhotoExif field and typed by it. Each calls exif() with the same opts
and returns that one field, or undefined when the file lacks it. A test
checks, on the JPEG fixture and on test/exif.heic, that every field
exif() returns has a method giving the same value. README and TODO.md
list them.

Model: opus-5-5
This commit is contained in:
2026-10-01 21:23:23 +00:00
parent 10e1a9ef39
commit f2f3395f94
4 changed files with 105 additions and 10 deletions
+7 -1
View File
@@ -726,7 +726,7 @@ synchronous getters look at the disk and never touch the network:
- `photo.isLocal` → `boolean` — whether the whole original is at `savePath`. A
copy only in the cache does not count.
Five async methods may download:
These async methods may download:
- `await photo.original(opts?)` → `{ path, bytes, videoPath? }` — the
full-resolution file. For a live photo, `path` and `bytes` are its image's and
@@ -748,6 +748,12 @@ Five async methods may download:
UTC. EXIF is read from any image format exifreader reads (such as JPEG,
HEIC/HEIF, AVIF, PNG, WebP and TIFF), a live photo's image included. Any other
original gives `{}`, and a video gives `{}` without being downloaded.
- `await photo.make(opts?)`, and likewise `model()`, `lensModel()`,
`dateTimeOriginal()`, `offsetTimeOriginal()`, `exposureTime()`, `fNumber()`,
`iso()`, `focalLength()`, `orientation()`, `gpsLatitude()`, `gpsLongitude()`
and `gpsAltitude()` → one field of `exif()` each, typed as in `PhotoExif`, or
`undefined` when the file lacks it. Each calls `exif()` with its `opts`, so
each call reads the original again.
They serve from the on-disk content cache when the bytes are present and
otherwise fetch through the pools; `original()`, `content()` and `exif()` also