Steganographic
Receipt System
Invisible watermarks · Full receipt payload · Phone camera decodes · AI understands
01
The problem
Receipts carry rich structured data but apps can only OCR them — unreliably. QR codes look ugly and break the receipt aesthetic. There's no invisible channel.
02
The idea
Encode the full receipt JSON into a subtle brightness pattern across the paper. Print it as a background texture. It looks like normal paper grain to the human eye.
03
The decode
Phone camera captures the receipt. Decoder reads the brightness grid, reconstructs bits, decompresses the payload. Full structured data — no OCR guessing.
04
The AI
Decoded JSON feeds directly to Claude with context: expense categorization, bill splitting, warranty tracking, return windows — zero transcription errors.
How it works — encoding algorithm
Receipt JSON
→zlib compress
→Frame payload
→Bitstream
→Noise carrier
→PNG texture
Magic
0xAF 0x01
16 bits
Length
uint16 LE
16 bits
Payload (zlib-compressed JSON)
variable
≤ 504 bytes = 4032 bits
CRC32
uint32 LE
32 bits
| Parameter | Value | Why |
|---|---|---|
| Texture size | 512 × 512 px | 4096 total 8×8 blocks |
| Block size | 8 × 8 pixels | Robust to print grain and blur |
| Encoding | Block average ± 14 vs. 128 baseline | Threshold decision, not LSB fragility |
| Capacity | 512 bytes (≈ 504 usable) | Typical 10-item receipt compresses to ~300B |
| Opacity | 6% default | Invisible to eye, readable by camera |
| Error detect | CRC32 + magic check | Catches bit errors from print noise |
Interactive demo — browser encoder
runs locally in JS · no server needed
1 — Enter receipt data
6%
2 — Texture output + decode
Encoded texture (zoomed in)
16× magnified — block pattern visible
Run encoder first...
Full stack — production API
steganography/
├── backend/
│ ├── encoder.py ← Receipt JSON → 512×512 RGBA PNG texture
│ ├── decoder.py ← Photo → deskew → block decode → JSON
│ ├── receipt.py ← Texture + layout → print-ready PDF
│ ├── ai_client.py ← Claude: expense / split / warranty / returns
│ ├── main.py ← FastAPI: /encode /decode /analyze /full-flow
│ └── schemas.py ← Pydantic models shared by all modules
└── frontend/
└── src/ ← React: capture → decode → AI display| Route | Input | Output |
|---|---|---|
| POST /encode | EncodeRequest | Base64 PNG + stats |
| POST /decode | Base64 image | Receipt JSON + confidence + CRC |
| POST /analyze | Receipt + mode | Claude expense/split/warranty/returns |
| POST /full-flow | Receipt | PDF + texture + AI analysis (one call) |
Start the API:
cd steganography/backend && uvicorn main:app --reload
Start the React UI:
cd steganography/frontend && npm install && npm run dev
cd steganography/backend && uvicorn main:app --reload
Start the React UI:
cd steganography/frontend && npm install && npm run dev