Commit Graph

34 Commits

Author SHA1 Message Date
admin 614ebb170b fix(gps): stop stamping the phone's current location on a picked photo
The library flow ended in a device-GPS fallback: whenever a photo's own
coordinates could not be read, getCurrentGPS() supplied the phone's present
spot, so the mark named wherever the user was standing instead of where the
photo was taken. Drop that tier entirely -- a photo with no readable location
gets no GPS mark. Also keep the legacy Android picker unconditionally so the
picked file keeps its EXIF GPS whatever the chip state, and prefer the city
over subAdminArea (county/district) as the displayed place name.
2026-09-10 17:08:09 +07:00
admin 423bf533f8 fix(gps): resolve place name when the watermark is switched on
A photo picked while the GPS chip was off kept its coordinates but no
locality (the geocode only ran when the chip was already on), and
handleToggleGeotag skipped GPS loading entirely when coordinates already
existed -- so switching the chip on showed STREET VIEW. Request location
permission inside reverseGeocode (expo-location's Android geocoder throws
LocationUnauthorizedException without it) and re-resolve the name from an
effect whenever the mark has coordinates but no place name. Both paths now
share localityName() so camera and photo stamps cannot disagree.
2026-09-10 17:01:48 +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 6595e5cbc1 Let the GPS and custom watermarks be rotated 2026-09-10 15:56:06 +07:00
admin e529c608f0 Keep the highlight slider off the greys, and start each mode clean
The highlight knee opened at 0.45, so dropping HIGHLIGHT pulled a mid-grey
down with the true highlights. It now opens at 0.65 (and the coefficient
drops 0.32 -> 0.22 to stay monotonic), so the slider leaves everything up to
a light grey untouched and still rolls the bright end off. Shadow is
untouched — its 0.00..0.55 knee was already right.

Switching between the library and the camera now drops the edits back to
the recipe's own values, no frame and no custom mark. A frame was picked
for the still it sat on and the mark was placed against that very photo, so
neither may follow the user across the switch (or into a live capture),
exactly like the sliders that were tuned on the photo in front of them.
2026-09-10 12:23:56 +07:00
admin bba2d76957 Keep the photo's colour when the highlight and shadow sliders move
Highlight/Shadow scaled R, G and B by one luma gain. That keeps the ratio
but crushes absolute chroma, so -SH turned a saturated blue into near-black
and -HL turned bright colours grey, and both sliders only bit at the very
ends of the range (knees 0.80..1.00 / 0.00..0.30) — they read as dead on
any photo without true whites or blacks.

The curve now moves the luma and carries the colour difference (rgb - luma)
along at clamp(gain, 0.55, 1.35), so hue survives darkening and lifting
instead of collapsing to black or white. Both knobs are pure additive luma
shifts with soft knees over the upper/lower half: the 0.50 midpoint moves
under 3%, and the curve stays monotonic (the old multiplicative form was
not — with hl=-1 a grey 0.73 came out darker than 0.80).

Kotlin applyTone port and the native bench probe gates follow.

Verified on device (4200x2800 probe: grey ramp + colour patches), library
export at ratio 4:3: -10 highlight leaves the darks alone and drops white
243->189 with the sky still blue; -10 shadow keeps blue as dark blue
(0,0,254)->(0,3,146), never black, ramp stays monotonic. Export keeps the
source 4200x2800 as well, so nothing is cropped.
2026-09-10 11:41:43 +07:00
admin 7c7a244b84 Rail without icons, FX glow chip renamed
The rail chips carried a lucide glyph before the label; drop the icons and
the icon field so the labels stand alone (the row is a plain text rail now,
and each chip is ~50px narrower). Also rename the FX knob from the
lens-vendor term to LIGHT GLOW - same key, same maths, just the label.
2026-09-10 10:44:33 +07:00
admin 6c7d5b8f43 Keep the existing COLOR chip label
Reverts the COLOR -> SATURATION rename: the control already existed, so
it stays as it was.
2026-09-10 10:28:38 +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 ff06045e02 Pinch/drag library photo inside polaroid & wall frame windows with export parity
The framed windows (polaroid card / wall frame opening) now take the same pinch + double-tap gestures as plain library, clamped so the photo keeps covering the mat opening, and the visible sub-rectangle is handed to the export engine so the file matches the preview.

Wall frame export also stopped crashing: on Android release an image asset resolves to a drawable *name* ('wallframe') and is flagged downloaded, so Asset.downloadAsync short-circuited and readAsStringAsync threw 'Unsupported scheme for location wallframe'. Clearing that state lets the native module copy the drawable into the cache.
2026-09-10 08:02: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 5799210949 Add embedded about & open-source credits screen (license audit) 2026-09-09 21:05:59 +07:00
admin 1cda62e039 P5 native export hooked (camera+library) — real photo to gallery on Xiaomi 2026-09-09 16:44:49 +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 a16c8734a8 Rotate wall frame portrait, letterbox feed to frame window 2026-09-08 18:14:25 +07:00
3dtours a1769e8c84 Add wall frame overlay with transparent PNG window 2026-09-08 17:56:50 +07:00
3dtours bfdc964f65 Polaroid print layout in viewfinder and export; split chip rows; drop cinematic; debounce EV bias 2026-09-08 16:30:29 +07:00
3dtours d2d62c6612 Sit library watermark at photo corner; white icons distinct from amber text 2026-09-08 12:12:47 +07:00
3dtours 58335d8cd1 Add one-space gap between watermark icons and text (preview + export) 2026-09-08 12:06:07 +07:00
3dtours b64d7245c9 Fix library GPS watermark anchor; use Cousine for Vietnamese glyphs 2026-09-08 12:02: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 ea281d7974 feat: monochrome Noto Emoji subset icons (pin, camera) before watermark lines 2026-09-08 11:30:47 +07:00
3dtours 43a73c541b fix: legacy picker for real photo GPS on Android 13+, watermark shows place + capture datetime 2026-09-08 11:28:02 +07:00
3dtours 358f9b0f2f fix: fresh export URI per save (stale thumbnail), lock spot-meter + quick EV slider, honor photo GPS over device fallback 2026-09-08 10:42:08 +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 200be77903 feat: full-res screen sharpen on camera-captured exports
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.
2026-09-07 16:48:16 +07:00
3dtours aa6a74f229 feat: stamp 300dpi metadata on camera-captured exports
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.
2026-09-07 16:31:24 +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 4c419f266c fix: lỗi áp dụng recipe lên live view của camera 2026-07-17 15:02:05 +07:00
3dtours 2775662b62 Bắt đầu sửa lỗi 2026-07-17 09:33:24 +07:00