Technical
Lossless vs re-encoded metadata removal, measured
Most online metadata removers re-compress your photo. Here is what that costs, how to tell whether a tool did it to you, and how to check for yourself.
Updated
There are two ways to remove metadata from an image, and the difference between them is not academic.
The easy way
Draw the image onto an HTML canvas, export it, hand back the result. Three lines of code:
const bitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
canvas.getContext('2d').drawImage(bitmap, 0, 0);
const clean = await canvas.convertToBlob({ type: 'image/jpeg', quality: 0.92 });
The metadata is gone, because canvas has no concept of metadata. It only knows pixels.
It also decoded your JPEG and encoded a brand new one. The output is not your photo with the metadata removed — it is a re-compression of your photo. Every block boundary has been recalculated, every coefficient requantised.
What that costs
Three things, in increasing order of how much they should bother you.
Quality. JPEG is lossy, so re-encoding always loses information. At quality 92 a single pass is subtle. It is not invisible in flat gradients, and it compounds: clean the same file twice and you have re-compressed it twice.
Predictability. The output quality is whatever the tool hardcoded. You did not choose it, and it is rarely disclosed. A photo saved at 100 comes back at 92.
Format identity. Browsers can decode HEIC in some contexts but generally cannot encode it. A canvas-based tool handed a HEIC will often quietly return a JPEG. You asked to clean a file and received a converted one.
The other way
Image formats keep the compressed picture and the metadata in separate places. A JPEG is a sequence of marker segments; the metadata sits in APP1, APP2, APP11, APP13 and COM, and the pixels live in the entropy-coded data after the start-of-scan marker.
So you can walk the segments, skip the ones you do not want, and copy the rest — including all the pixel data — through byte for byte. Nothing is decoded, so nothing can degrade.
The same principle applies everywhere, with a different mechanism per format. PNG is a chunk chain, so you filter chunks. WebP is RIFF, so you filter chunks and fix the VP8X feature flags. HEIC and MP4 record absolute byte offsets, so you cannot delete bytes at all — you overwrite the metadata in place instead, leaving every offset valid.
It is more work. It is roughly one parser per container. But it means “remove metadata” costs you nothing.
How to tell what a tool did to you
You do not have to take anyone’s word for it.
Check the file size. Metadata in a typical photo is a few kilobytes. If a 4 MB JPEG comes back as 2.6 MB, several megabytes of pixel data went missing. That is a re-encode, not a metadata strip.
Compare the pixels. With ImageMagick:
magick compare -metric AE original.jpg cleaned.jpg null:
0 means every pixel is identical. Any other number means the image was re-encoded. With Python:
from PIL import Image, ImageChops
a, b = Image.open("original.jpg"), Image.open("cleaned.jpg")
print(ImageChops.difference(a.convert("RGB"), b.convert("RGB")).getbbox())
None means identical.
Check the quantisation tables. A re-encoded JPEG has the encoder’s tables, not your camera’s. exiftool -QuantizationTable will show you.
Why this site verifies it in the browser
Because a claim you cannot check is just marketing. After every removal here, both files are decoded and every channel of every pixel is compared. When the result says zero pixels changed, that is a measurement taken on your machine, and it goes into the audit report you can download.
Where a browser cannot decode a format — HEIC frequently — it says “not compared” rather than guessing. The removal is unaffected; only the automated proof is.