fix(photos): shared EXIF-oriented decode for axis/overlay space (#72)

PhotoStage used new Image() while mask worker and calculate used bare
createImageBitmap; Orientation-8 matched-set JPEGs can disagree across
those paths so the approved pink axis is not the overlay (ux,uy).

One decodeOrientedBitmap helper always requests imageOrientation
from-image (with bare fallback), wired into PhotoStage, mask.worker,
and session calculate/siblings.
This commit is contained in:
2026-09-16 05:08:13 +00:00
parent b8e69b5239
commit 037a4b870a
6 changed files with 299 additions and 79 deletions
+3 -2
View File
@@ -10,6 +10,7 @@ import { measure } from '../measure/measure';
import { orientedRect } from '../geometry/rect';
import { encodeInventoryPng, type InventoryInput } from '../png/inventory';
import { encodeOverlayPng, type EncodeOverlayInput } from '../png/overlay';
import { decodeOrientedBitmap } from '../decodeOrientedBitmap';
const DEBOUNCE_MS = 2000;
const BUSY_MS = 300;
@@ -512,7 +513,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
if (state.k !== 'measure') return;
const { source, approvedMask, axis, lengthEighths, thicknessEighths } = state;
if (lengthEighths === 0 || thicknessEighths === 0) return;
const bitmap = await createImageBitmap(source.blob);
const bitmap = await decodeOrientedBitmap(source.blob);
const base = measure(
approvedMask.bitset, source.widthPx, source.heightPx,
axis.bbox, lengthEighths, thicknessEighths, approvedMask.slabPx,
@@ -587,7 +588,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
widthPx: derived.widthPx,
heightPx: derived.heightPx,
};
const siblingBitmap = await createImageBitmap(photo.blob);
const siblingBitmap = await decodeOrientedBitmap(photo.blob);
let encoded: { blob: Blob; sourceBelowFloor: boolean };
try {
encoded = await encodeInventory({ bitmap: siblingBitmap, mask: derived.mask, source: siblingSource });