Why a browser canvas wipes C2PA credentials
C2PA — the Coalition for Content Provenance and Authenticity — is the system Adobe, Microsoft, and friends use to sign AI-generated images. On Instagram and Facebook, a signed C2PA manifest is what triggers the "Made with AI" label.
The signatures are cryptographic. The manifests are tamper-evident. It sounds robust.
It is, until you remember one detail: C2PA travels in a container, not in the pixels.
What a JPEG actually looks like
A JPEG file is a series of markers. The pixels live inside SOI, SOF, DQT, and SOS segments. Metadata — EXIF, XMP, IPTC, ICC, and C2PA — lives in APP* segments alongside them. PNG works the same way with tEXt, iTXt, and dedicated caBX chunks for C2PA.
When you open the file in a browser, the decoder reads the pixel segments into a raw bitmap. It walks past the metadata.
What <canvas>.toBlob() does
const canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
canvas.getContext("2d").drawImage(img, 0, 0);
canvas.toBlob(blob => { /* clean file */ }, "image/jpeg", 0.95);
The browser re-encodes a brand-new JPEG (or PNG, or WebP) from the in-memory bitmap. There is no metadata to copy, because the bitmap has none. C2PA manifests, EXIF GPS, Stable Diffusion parameters chunks — all of it lived outside the pixel grid, and none of it survives.
What this does not fix
- Pixel-level watermarks. If a model bakes a low-amplitude pattern into the pixels themselves (think SynthID), re-encoding preserves it within JPEG quantization tolerance. You'd need pixel perturbation, which AI Info Remover offers as an optional step.
- Perceptual hashing. Platforms can match images against a database by content-similarity hashes. Re-encoding usually doesn't shift those hashes far enough to matter. The "scramble hash" option adds sub-perceptual noise to handle this.
- Visible content. We're not in the business of editing what's in your photo.
The takeaway
A 30-line HTML file does in your browser what a backend service charges $5/month for. The privacy story is honest because there is no server to trust — disconnect from the internet after the page loads and the tool still works.