3.8 KiB
Inner Shadow Ground Truth — PNG Pipeline (no PSD needed)
Problem
The Rust PSD writer (hcie-psd/src/psd_saver.rs) produces files that pass Psd::from_bytes internally but cannot be opened in Photoshop. We've spent multiple rounds fixing the PSD format (layer extra data, lfx2 padding, merged image layout, 8BIM blocks) without success.
Root cause: The PSD binary format is extremely complex (200+ page spec). Getting every field exactly right for Photoshop's parser is a long, error-prone process.
Solution: Skip PSD entirely
The Photopea JSX script at _tools/photopea/generate_inner_shadow_dataset.jsx already creates ground truth PNGs directly — no PSD intermediate needed. Photopea/Photoshop is the renderer; it applies inner shadow via its own engine and exports transparent PNGs.
This is the simplest, most reliable path to ground truth.
Plan
Step 1: Generate Ground Truth PNGs via Photopea
The user opens Photopea (https://www.photopea.com) in a browser and runs the existing JSX script. It will:
- Create 256×256 transparent documents
- Add a layer with a black centered rectangle (50% margin)
- Apply Inner Shadow via ActionDescriptor (Photoshop's native effect engine)
- Save transparent PNG
Parameter grid (192 images):
| Param | Values |
|---|---|
| angle | 0, 90, 180, 270 |
| distance | 5, 15, 30 |
| size (blur) | 10, 30 |
| choke | 0, 20 |
| fx opacity | 75, 100 |
| fx blend mode | Normal, Multiply |
Output: _tmp/is_ground_truth/ directory with PNGs like is_a0_d5_s10_c0_op75_bmnormal.png.
Step 2: Write Rust MAE Tuning Example Against PNGs
Create hcie-io/examples/tune_mae_inner_shadow_grid.rs that:
- Loads ground truth PNGs from
_tmp/is_ground_truth/ - Parses the filename to extract parameters (angle, distance, size, choke, opacity, blend mode)
- Recreates the same shape (256×256, black rectangle at 25% margin) in Rust
- Calls
generate_inner_shadow_tuned()with the same parameters - Blends the shadow with the shape using the specified blend mode and opacity
- Computes MAE against the ground truth PNG
- Grid-searches blur_factor, passes, choke_scale, mask_strength across the full dataset
- Reports best global parameters and per-combo breakdown
Key differences from the existing tune_mae_inner_shadow.rs:
- Works against multiple parameter combos (192 PNGs), not a single PSD
- Loads PNG files directly (no PSD import needed)
- Creates the shape geometry from scratch (no PSD layer needed)
- Reports per-combo MAE for diagnostics
Step 3: Run and Report
cargo run --package hcie-io --example tune_mae_inner_shadow_grid
Expected output: best blur_factor, passes, choke_scale, mask_strength with average MAE across all 192 combos.
Step 4: Apply Best Params to tuned.rs
Update hcie-fx/src/tuned.rs generate_inner_shadow_tuned() if new best params differ from current (blur_factor=1.45, passes=3, choke_scale=0.0, mask_strength=1.0).
Files to Create/Modify
| File | Action |
|---|---|
hcie-io/examples/tune_mae_inner_shadow_grid.rs |
Create — grid search against PNG ground truth |
hcie-fx/src/tuned.rs |
Modify (if params change) |
Files NOT Modified
hcie-psd/src/psd_saver.rs— no more PSD fixes needed_tools/photopea/generate_inner_shadow_dataset.jsx— already works as-is
User Action Required
- Open https://www.photopea.com in a browser
- Press
Alt+Ctrl+I(or File → Automate → Script) - Paste contents of
_tools/photopea/generate_inner_shadow_dataset.jsx - Select output folder: create/choose
_tmp/is_ground_truth/ - Wait for ~192 images to generate
- Tell me when done — I'll run the Rust tuning example
Verification
After tuning, generate a test inner shadow with our engine and visually compare against one of the Photopea PNGs side-by-side.