Files
RecipesCam/RELEASE_NOTES.md
T

7.7 KiB
Raw Blame History

Release notes

1.2.7 (versionCode 9)

Export

  • Every camera capture came out of the exporter through a full-resolution unsharp mask the viewfinder never showed. App.tsx passed sharpen: true, and with the SHARPENING knob at its default 0 both engines read that flag as an amount of 0.5 - a value that existed only as the boolean's fallback. The 3x3 kernel [0,-a,0; -a,1+4a,-a; 0,-a,0] at a=0.5 has a noise gain of 3.167x at low frequency and 5.0x at Nyquist, so a dim, high-ISO frame was pushed back several times noisier than the preview promised.
  • The knob is now the only source of output sharpening. The boolean is gone from ExportOptions and NativeExportOptions, the 0.5 fallback is gone with it, and screenSharpenImage no longer carries amount = 0.5 as a default argument - a second door onto the same value. A knob above 0 sharpens exactly as before, the negative knob still means none, and the Kotlin-side adjust["sharpen"] amount is untouched.
  • Measured on a Xiaomi thor, 3000x4000 captures in one unchanged scene. At 1x / ISO ~330 the noise sigma drops 4.52 -> 2.35, the dark-quartile sigma 3.21 -> 1.56 and a flat 64px tile 0.599 -> 0.349; at 10x / ISO ~1900 the same three fall 1.22 -> 1.09, 0.75 -> 0.54 and 0.464 -> 0.225. With no edit applied, the JPEGs shrink 26% and 35% - the mask had also been spending a third of every file on amplified noise.
  • Stills now match the preview, which always rendered without the mask.

Notes

  • qualityPrioritization was re-tested as the other suspect and cleared: MAXIMIZE_QUALITY ('quality') moved neither noise figure at either ISO, so the shipped 'balanced' capture mode stays.
  • Zoom to 10x in the same room is the high-ISO bench for this device: AE picks ISO ~1900-2100 there against ~330 at 1x.

1.2.6 (versionCode 8)

Presets

  • New film sim B&W HIGH CONTRAST, next to ACRIPES. Acros' grey ramp taken through a warm filter mix - red 0.38 / green 0.56 / blue 0.06, the three rows equal and summing to 1.00, so a neutral stays the neutral the sensor recorded and nothing clips at either end - and then pushed at both ends: the toe goes to -0.32 against Acros' -0.12, and the shoulder LIFTS to +0.26 instead of rolling off. Midtones see neither mask, so the long smooth stretch between the two ends survives, which is what keeps that hard a push off the posterised look.
  • The stock's own slope (+4 of Contrast) is not in the sim's adjustments: the panel still reads EXPOSURE 0 / CONTRAST 0, and FX still reads GRAIN 0 / CLARITY 0, while the render comes out pushed. It rides STOCK_BIAS in colorUtils.ts, keyed by baseFilter - the old STOCK_EXPOSURE table folded in, one place for the tone a stock carries by itself (LC STREETLIFE VIVID exposure +2, B&W HIGH CONTRAST contrast +4).
  • Two black-and-white stocks exist now, so every "is this a colour stock?" test goes through the new isMonochromeBase(): saturation, white balance and the R/B fine-tune in the matrix, Color Chrome in the tone shader. A second B&W stock can no longer end up half excluded - a stray Kelvin gain on a grey ramp shows up as a tint.
  • Measured against the compiled tables: a 0.25 grey goes 0.2500 -> 0.2250 (the +4 slope pivoting on mid-grey 0.5), a full red goes 0.213 -> 0.368 while blue drops to 0.016, and colour-stage knobs moved hard (saturation +8, white balance 9000K, wbR +5 / wbB -5) leave both B&W matrices byte-identical.
  • On a Xiaomi thor: the chip sits right after ACRIPES, its preview reads mean chroma 0.00 against 17.48 for a colour sim, and the frame's luma spread widens as designed (sd 92.3 / p95 245 against ACRIPES' 88.9 / 238).

1.2.5 (versionCode 7)

Presets

  • A film sim is a stock, not an edit: every entry in FILM_SIMS now carries the neutral defaults verbatim, and its whole look comes from the stock's own colour matrix plus its FILM_TONE curve. The effects that had been riding along are gone - grain on ACRIPES, clarity+grain on LC STREETLIFE CLASSIC, and exposure/saturation/clarity/shadow/highlight on LC STREETLIFE VIVID.
  • LC STREETLIFE VIVID is brighter because the stock is brighter, not because a slider was moved: the +2 exposure lives in STOCK_EXPOSURE (colorUtils.ts), keyed by baseFilter, where the preview and both exporters already read it. It never reaches the panel, so EXPOSURE still reads 0 on that sim.
  • The naming rule is recorded in the FILM_SIMS header: colour and tone only, plus a reference table of the real stock each sim stands for. Reference only - the UI keeps the sim names.
  • Measured against the compiled tables: a mid grey goes 0.5000 -> 0.5435 under LC STREETLIFE VIVID, a ratio of 1.1008 against exposure +2's own 1.1000, while the sim's own exposure value stays 0.

1.2.4 (versionCode 6)

HSL

  • New HSL tab in the tool rail: the web studio's 8-band selective colour mixer. Each band (RED, ORANGE, YELLOW, GREEN, AQUA, BLUE, PURPLE, MAGENTA) carries hue, saturation and lightness knobs, -10..+10; -10 on SAT is grey, full HUE is a 30 deg turn, full LUM is +0.25.
  • Band weights are linear tents anchored on the 8 hues and summing to 1 at every hue, so neighbouring bands hand over at exactly half strength and no hue falls in a gap. Pixels under 8% saturation are gated out of the weights (rgb2hsl calls them red, and an ungated neutral would ride the RED band), while the whole-image LUM move is added after the gate, so a picture pulled to grey by -SAT still answers +LUM.
  • The mixer runs last in TONE_SKSL, after split-tone/kv and vibrance, so a band edit is judged on the colour the user actually sampled.
  • Library mode gains an eyedropper: PICK arms a layer over the picture, a tap reads the rendered pixel, points the ruler at the nearest band and hangs a panel with that band's three knobs. In camera mode PICK is greyed out - a live preview has no pixel to read - but the mixer still runs in the preview.
  • HUE / SAT / LUM IMAGE move every hue at once, behind an IMAGE divider in the same chip row.

Rail

  • Tool rail order: PRESETS, FAVORITED, WB, LIGHT, FX, HSL, FRAME.

Notes

  • HSL is a LITE feature: both builds get it, no PRO gate.
  • MONOCHROME disables the mixer outright - a mono stock has no hue to select.
  • The camera worklet's tone buffer grew from 10 to 40 slots; a missed slot would have pushed NaN into every uniform and broken the whole tone pass, not just HSL.
  • Measured on a Xiaomi thor against an 8-band chart: +10 whole-image HUE rotates all eight bands by exactly +30 deg, -10 on a band's SAT flattens that band to grey while the other seven stay put, and a whole-image -SAT drops the camera preview's mean chroma from 13.7 to 0.4 with +LUM still lifting it 116 -> 166.

1.2.3 (versionCode 5)

Shutter

  • The shutter no longer waits on GPS: the fix is prewarmed at launch and bounded by a 2 s deadline, so a tagged shot reaches the gallery in about 3 s instead of 12–25 s.
  • A shot pressed before the camera session binds is queued and replayed, not dropped.
  • Fixes "Capture Failed — Could not take the photo.": capturePhotoToFile needs both its settings and options arguments.
  • Saving to the gallery no longer depends on the media permission — the native save runs first, MediaLibrary only as a fallback.

Memory

  • The Skia surface and bitmap are released after every export, dropping one full-resolution copy per rotation; the watermark font is parsed once.

Cold start

  • The JS bundle is stored uncompressed in the APK.
  • Named Lucide imports are rewritten to per-icon modules, so only the icons the app renders are bundled: 4.66 MB → 3.40 MB (−27%).
  • The export pipeline and the recipe/GPS helpers load on demand.
  • Hidden modals render nothing.

Measured on a vivo V2430 (Android 16) with a force-stop/start/tap probe: the earliest tap that reliably lands a photo moved from ~1.8 s to ~1.6 s once the bundle was trimmed. The rest is spent before app JS — process init, SoLoader, Hermes eval.