Commit Graph

18 Commits

Author SHA1 Message Date
admin a85ebf0a81 Sell PRO as an in-app unlock, take shared photos, and let FX run negative
- One free Play app (com.locphamtran.recipescamera) with an expo-iap PRO
  unlock, replacing the paid apk for the store channel
- Android SEND/SEND_MULTIPLE share target feeds photos into the editor,
  on cold start and on resume
- BACK button in the TopBar and press-and-hold PEEK replace the chip row
- NOISE REDUCTION and SHARPENING accept -10: a negative SHARPENING softens
  the frame before the grain pass, a negative NOISE REDUCTION re-grains it,
  in the Skia engine, the live preview and the Kotlin export path alike
2026-09-16 06:48:22 +07:00
admin 97949e449d Ship LITE and PRO, and let CLARITY and LIGHT GLOW reach the library
Both flavors build from one JS tree: `lite` hands out the free apk
(com.locphamtran.recipescamera), `pro` sells as-is (same id + .pro, label
"RecipesCam Pro"). Release is signed from android/keystore.properties, both
files gitignored - lose either and no later build can install over this one.
The tier reaches JS through src/provariant.ts, which tools/set-variant.mjs
rewrites before each build (`npm run apk:lite` / `apk:pro`); the gradle flavor
alone would ship a Pro apk that thinks it is Lite.

The dev scaffolding goes: the three src/dev probes and their App effects, the
EXPO_PUBLIC_CAPTURE_MODE [CAPTURE] timing log, and the -PdevtestSuffix
side-by-side install hook. 'balanced' stays the shipped capture mode, which is
what those probes measured on the 12S Ultra.

Looking at the picture: WB now converts kelvin through the Planckian locus into
a luma-normalised gain (unity at 5500K, symmetric tint) instead of the old
one-sided push; LEITZ STREETLIFE splits into CLASSIC and VIVID; selecting a
recipe loads every knob it carries over the defaults and stays editable, and
RESET hands the panel back to the sim's own values. The in-app library picker,
the ultra-wide native module and recipe share/import land here too.

CLARITY and LIGHT GLOW existed only on the camera worklet and the export
engine, so a photo opened from the library ignored both. They now run in all
three library preview branches (libPhoto), and the preview clips them to the
drawn image - the export engine always clipped its bloom to the canvas, the
preview drew it over the whole rect, so the bloom bled past the photo onto the
black letterbox and over the frame's mat.
2026-09-14 19:48:44 +07:00
admin 93f48537f8 feat(frame): CROP ratios in the library editor, and the framed-photo fixes
CROP chip on the FRAME tab for the library's plain frames: NONE, FREE
(drag the box) and the fixed ratios 1:1, 2:3, 3:2, 3:4, 4:3, 16:9. The
preview draws the keep-rectangle over the photo and the export honours it
pixel-for-pixel, pinching and dragging inside the band to pick the framing.

- Viewfinder: build frameRect from the normalised rect so the Skia canvas
  never sees undefined width/height (nothing to commit until now), keep
  the watermark drag target across the WATERMARK tab so a zoomed photo
  no longer resets, and derive the crop band + export rect from the photo
  fit rect.
- exportEngine: crop by fraction rect (or the ratio fallback) before the
  frame is composited.
- Leaving a plain frame clears the crop, and the ratio strip closes with
  the CROP chip it belongs to.
2026-09-10 20:12:03 +07:00
admin 299d81bade feat(wm): GPS watermark color + place-name/time toggles, "commune, city" locality 2026-09-10 18:05:57 +07:00
admin 11ed786758 Let the GPS watermark be placed, sized and hung landscape
Three WATERMARK/FRAME behaviours that share the stamp geometry:

* GPS mark: drag it anywhere on the frame/photo area and pinch it bigger or
  smaller. The 0..1 anchor plus the size multiplier ride along in the export
  options, so a framed file (whose canvas IS the card/frame) burns the mark in
  at exactly the fraction the preview showed.
* The photo's own pinch zoom stays available while the WATERMARK editor is
  closed, so a two-finger zoom is never swallowed by the mark while its panel
  is open.
* WALL FRAME gains a WALL PORTRAIT / WALL LANDSCAPE chip: the artwork hangs
  in its own 4000x3117 orientation instead of the default 90-degree rotation.
2026-09-10 16:35:35 +07:00
admin 65d0850317 FX vignetting, LIGHT vibrance/saturation, reticle unlock
- FX: new VIGNETTING 0-10 control (chip + slider). Darkens the four
  corners of the photo with a radial gradient whose radius is the photo
  diagonal/2, so the falloff stays circular on any aspect. Applied in
  preview (camera overlay, polaroid/wall window, plain library) and in
  exportEngine pass 6b, always on the picture, never on the mat.
- LIGHT: new VIBRANCE -10..+10 (chroma-masked saturation in the tone
  shader: vivid pixels move least). Renamed the existing saturation
  control chip from COLOR to SATURATION - same param, clearer label.
- Fix: <Shader> takes a RuntimeEffect, not a gradient SkShader; the
  preview vignette threw "Object is not a HostObject" when it got one.
  Use the declarative <RadialGradient> child on the Rect instead.
- Preview: drop the "AE/AF LOCKED - TAP TO UNLOCK" banner; the lock
  reticle is now itself the unlock touch target.
2026-09-10 10:22:55 +07:00
admin 28e18893cd Add HDF (Highlight Diffusion Filter) to the FX tab
The built-in lens filter, simulated the way it is done in Photoshop: pull the
highlights out with a hard contrast curve (out = 2.5*in - 1.5, black below 0.6),
Gaussian-blur that selection, then Screen it back over the photo at reduced
opacity. Screen against a near-black pixel is a no-op, so areas with no
highlight within the blur radius come back byte-identical while lit areas
spread their light.

One 0..10 knob drives both the radius (4%..1.9% of the width, ~10..50px at
2560 wide) and the opacity (0.15..0.5), matching the recipe's 15-50px radius
range. The extraction composes on top of the recipe colour matrix so a
monochrome look glows white instead of leaking the original colours back.

Runs in the Skia export engine only; the P5 native path is not wired into the
app (dev parity probe only), so it is left alone for now.
2026-09-10 09:45:51 +07:00
admin 3a8b110c1b Edit the watermark in place, rotate the frame photo, place a custom watermark
Watermark editing no longer covers the photo: the preview letterboxes the
image inside its fit rect while the deck is open, and the idle hint is gone.

The FRAME tab can rotate a library photo 90 degrees clockwise. Rotation
swaps the pixel dimensions instead of the frame, so the polaroid/wall window
keeps its aspect and every consumer (cover crop, watermark area, export) picks
up the new orientation from width()/height() with no extra layout branch. The
rotate surface is CPU-backed on purpose - a GPU snapshot loses its pixels
before the next frame and renders the photo black.

Custom watermark text can now be dragged anywhere on the photo, double-tapped
to re-edit, and is only baked into the file once ACCEPT is pressed; the export
engine takes the same position. It also gained COLOR/SIZE/FONT chips, with the
font list read from the OS via Skia's FontMgr so any installed family can be
used.
2026-09-10 09:26:55 +07:00
admin 144b211d35 Add WATERMARK tab with custom draggable text; hide FRAME in camera; fix double-dark after highlight capture 2026-09-10 07:17:14 +07:00
admin ca3532023a Startup mode default/last-session; GPS watermark default OFF; shutter OFF truly silent
- Settings STARTUP MODE chips (AsyncStorage startup_mode): default = clean camera
  + PROVIA neutral 4:3, last = restore full session look.
- initSession: resolve sim-* recipe ids via FILM_SIMS (fix clobber of session
  ratio/adjustments to 4:3 canonical); restore via setSelectedRecipe not
  applyRecipe so user tweaks (frame/geotag/ratio) survive restore.
- applyDefaultStartup turns GPS watermark OFF (user-requested default).
- Shutter: OFF must not play click on must-play-policy devices. VisionCamera
  v5.2.3 HybridPhotoOutput.kt plays MediaActionSound itself gated by
  (enableShutterSound ?: true) || mustPlayShutterSound — on Xiaomi mustPlay=true
  so OFF still clicked. Both capture paths now gate on enableShutterSound != false.
  node_modules patch not trackable -> artifacts/patches/vision-camera-shutter-silent.patch.
  Verified on Xiaomi 12S Ultra: log SND user=false -> play=false; cold-start
  DEFAULT shows GPS WATERMARK OFF.
2026-09-09 17:59:15 +07:00
3dtours bd7efce600 feat(presets): add LEICA simulation chip; collapse recipe strip on sim select 2026-09-09 11:32:30 +07:00
3dtours 09dbc72cce feat: v1.1 — highlight-weighted metering, settings modal, photo viewer, shutter sound control, cleanup 2026-09-09 09:41:55 +07:00
3dtours d43405a4de Add aspect-ratio composition band and RAW DNG sidecar capture 2026-09-08 18:43:02 +07:00
3dtours a1769e8c84 Add wall frame overlay with transparent PNG window 2026-09-08 17:56:50 +07:00
3dtours 588a36d05a feat: cinematic seasonal atmosphere presets (spring/summer/autumn/winter) - enhances existing light with season tints, sun glow, fog veil 2026-09-08 11:38:27 +07:00
3dtours 8eca31ce58 fix(camera): matrix-based zoom for pinch/double-tap, tap-to-focus AE/AF lock, library letterbox smear fix, export raw JPEG bytes q95, resume isActive fixes, dark theme polish 2026-09-08 10:25:34 +07:00
3dtours 96f412e269 fix: sửa export/gps/UI theo FIX_PLAN + chụp ảnh camera thật (takePhoto)
- export: encodeToBase64 thay SkData.toString, dùng expo-media-library/legacy
- GPS ảnh gốc: resolver EXIF -> MediaLibrary -> device (ACCESS_MEDIA_LOCATION), tag nguồn watermark
- contrast vào color matrix (có hiệu lực mono), ẩn highlight/shadow, denoise/clarity ghi chú export-only
- init session tuần tự, tách setState lồng nhau, share file bằng expo-sharing, DONE lưu gallery
- Phase 4A: chụp camera thật qua vision-camera takePhoto rồi export filter
2026-09-07 06:54:13 +07:00
3dtours 2775662b62 Bắt đầu sửa lỗi 2026-07-17 09:33:24 +07:00