SkiaCamera cover-fits the upright frame snapshot onto the fullscreen view,
so a 4:3 ratio band (aspect == native 3:4 sensor) only revealed a center
slice of the sensor instead of the whole frame. Redraw the feed inside the
frame worklet: when a photo-area rect is active (ratio band / polaroid
window / wall window) black the surface, clip to the rect's raw-frame
inverse under the renderToTexture rotation/mirror CTM, and cover-map the
sensor there. Equal-aspect bands now show the full sensor; narrower ratios
(3:2) crop center like the export. Inactive feed keeps the legacy draw.
useCameraDevices fetches once on mount. First-run flow grants the
camera permission after the viewfinder mounted, so the device list
stays empty until remount/restart and the UI shows 'Camera not
available on this device'. Poll Camera.getAvailableCameraDevices()
for up to 6s after permission is granted and prefer the found device.
Lightroom-style 'Screen' output sharpen (unsharp mask, 3x3 convolution
via Skia ImageFilter.MakeMatrixConvolution, amount 0.5, kernel sums to
1) applied to final pixels before JPEG encode. Camera-capture branch
passes { dpi: 300, sharpen: true }; library-mode export untouched.
Export pixels were already full resolution - sharpen is a new final
GPU pass, no pixel-count change.
Skia JPEG re-encode drops original header (72dpi camera default). New
src/utils/jpegDpi.ts rewrites JFIF APP0 density + EXIF X/YResolution
(endian-aware) or inserts minimal JFIF when neither exists; applied via
processAndExportPhoto options.dpi in the camera-capture branch only.
Library-mode exports untouched. Pixels never change - metadata only.