Encode
Embed a payload into a photo.
Embed 896 invisible bits into any image, then recover them after a JPEG round-trip, a resize, or a social-platform pipeline. Everything runs on your device.
Embed a payload into a photo.
Recover the payload β optionally through a channel attack.
What it is. Live demo of the MWIP watermark β an invertible
neural network embeds an 896-bit payload (H = 128-bit perceptual hash,
sig = 512-bit Ed25519, pk = 256-bit public key) into an
image, and a sibling network recovers it after channel distortion.
Demo caveat. The keypair ships in this page; anyone can forge a valid signature. Real deployment uses device-bound secret keys. The pHash is a placeholder.
Where this runs. ONNX Runtime Web in a Web Worker, on your device. Your image is never uploaded. Out of scope for the current model: crop, rotate, Gaussian noise, Gaussian blur.
Image size cap. The decoder allocates ~12 MB of float32 per megapixel plus ~60β120 MB of forward-pass intermediates. The demo caps input at 1 MP on desktop (WebGPU) and 0.5 MP on mobile (WASM on iPhone, where Safari's per-tab memory budget is tight). The model itself has no such limit β on a phone NPU or server it runs the full image.
Production speed per pass (encode β decode β same INN backbone):
| Photo size | Pixels | Phone NPU | Server GPU fp16 | Server CPU AVX-512 |
|---|---|---|---|---|
| Instagram post | 1080Γ1080 (1.2 MP) | ~80 ms | ~7 ms | ~30 ms |
| 1080p screen capture | 1920Γ1080 (2.1 MP) | ~140 ms | ~12 ms | ~55 ms |
| iPhone screenshot | 1179Γ2556 (3.0 MP) | ~200 ms | ~17 ms | ~80 ms |
| 16β³ MacBook screenshot | 3456Γ2234 (7.7 MP) | ~510 ms | ~45 ms | ~200 ms |
| Phone camera (default) | 4032Γ3024 (12 MP) | ~1.0 s | ~70 ms | ~300 ms |
| Phone HQ / iPhone 24 MP | 5712Γ4284 (24 MP) | ~2.0 s | ~140 ms | ~600 ms |
| Full-frame DSLR | 7008Γ4672 (33 MP) | ~2.7 s | ~190 ms | ~830 ms |
Browser-WASM mobile is ~100β500Γ slower than the phone-NPU target; server GPU is ~10Γ faster again.