Skip to content

fix(images): use EXIF-oriented dimensions in metadata refresh#475

Merged
Zheaoli merged 1 commit into
mainfrom
fix/metadata-refresh-orientation
May 30, 2026
Merged

fix(images): use EXIF-oriented dimensions in metadata refresh#475
Zheaoli merged 1 commit into
mainfrom
fix/metadata-refresh-orientation

Conversation

@Zheaoli
Copy link
Copy Markdown
Collaborator

@Zheaoli Zheaoli commented May 30, 2026

Fix: EXIF-oriented dimensions in the metadata-refresh task

A pre-existing correctness bug surfaced during the image-performance work (parent task #1, raised by @Picimpact-Review during BE-2 review).

Problem

server/tasks/metadata-refresh.ts read image dimensions via sharp(buffer).metadata() without accounting for EXIF orientation. sharp reports the stored (pre-rotation) width/height, so for orientation 5–8 (rotate 90/270/transpose/transverse — common on phone photos) the task persisted swapped images.width/images.height. The gallery (and the new variant pipeline) treat those as displayed dimensions, so rotated photos laid out as landscape-when-portrait, and the bad values would also overwrite the correct browser-reported dimensions stored at upload time.

This is the same orientation issue fixed inline in the BE-2 variant generator; this PR makes the handling consistent so the two code paths that write images.width/height agree.

Change

  • Extract the orientation-swap logic into a shared getOrientedDimensions(metadata) helper in server/lib/image-variants.ts, and use it in generateImageVariants (behavior-preserving refactor).
  • Use the same helper in metadata-refresh.ts (the actual fix).

Verification

  • Empirically checked against sharp 0.34.5 for all EXIF orientations 1–8: helper output equals the actual .rotate() pixel dimensions (1–4 unchanged, 5–8 swapped) — see below.
    orientation=1..4: 200x100 (no swap)   orientation=5..8: 100x200 (swap)   ALL PASS
    
  • tsc --noEmit: no errors in changed files. eslint --fix: clean.

Independent of the BE-3 queue work; safe to review/merge on its own.

🤖 Generated with Claude Code

The metadata-refresh task read image dimensions via sharp(buffer).metadata()
without accounting for EXIF orientation. For orientation 5-8 (rotate
90/270/transpose/transverse — common on phone photos) sharp reports the
stored, pre-rotation width/height, so the task persisted swapped dimensions
to images.width/height. Because the gallery (and the new variant pipeline)
treat those as displayed dimensions, rotated photos were laid out as
landscape-when-portrait, and the bad values would also overwrite the correct
browser-reported dimensions stored on upload.

Extract the orientation-swap logic introduced in the variant generator into a
shared getOrientedDimensions() helper and use it in both image-variants.ts
(behavior-preserving refactor) and metadata-refresh.ts (the fix). Verified
against sharp 0.34.5 across EXIF orientation 1-8: helper output matches the
actual .rotate() pixel dimensions (1-4 unchanged, 5-8 swapped).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
picimpact Ready Ready Preview, Comment May 30, 2026 11:32am

@Zheaoli Zheaoli merged commit 46690db into main May 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant