QR File Transfer

Send files between two devices using only the camera. Protocol: QRT1

Sender

No file selected.

Receiver

Camera input is processed locally in your browser only and is not uploaded to any server.

Idle.

Protocol QRT1

Each QR code encodes one UTF-8 text frame. Fields are separated by |.

Header frame

QRT1|H|<sid>|<totalChunks>|<fileSize>|<chunkSize>|<mime>|<base64Name>|<colorLevels>

Data frame

QRT1|D|<sid>|<index>|<base64Data>
  • sid: 6-char random session id, prevents mixing transfers.
  • index: 0-based chunk index.
  • base64Data: standard base64-encoded raw bytes of the chunk.
  • base64Name: base64-encoded UTF-8 filename.
  • colorLevels: brightness levels per RGB channel used by the sender — 1 = B&W, 2 = 8-color (3 frames/image), 4 = 64-color (6 frames/image). Optional for backward compatibility; missing = 1.

The sender loops continuously through all chunks and re-emits the header every 8 frames so the receiver can join at any time and recover from missed frames.

Color QR mode

To increase per-image capacity, the sender can pack multiple QRT1 frames into one image by writing each frame into a separate bit-plane of the RGB channels.

  • 8 colors — each channel has 2 levels (dark / light). One QR per channel → 3 frames per image. Colors: white, black, cyan, magenta, yellow, red, green, blue.
  • 64 colors — each channel has 4 brightness levels (0, 85, 170, 255). Two QRs per channel (high bit + low bit) → 6 frames per image. Requires reasonably accurate camera color reproduction.

All QRs in one image share the same version/module grid so they align pixel-for-pixel. The receiver splits each captured frame back into per-channel grayscale images (using adaptive min/max thresholding so screen brightness and camera white balance can drift), reconstructs the bit-planes, and decodes each binary QR independently. Plain B&W QRs still decode in color mode because R=G=B.