Your JPEG logo has two whites now

Why "select same fill" deletes the wrong white after tracing a JPEG logo, how to count the whites in the SVG, and how to drop only the background.

Someone sends a logo. Navy box, company name knocked out in white. It's a JPEG, because it's always a JPEG. You trace it, you want the white gone so it sits on a shirt or a cut sheet, and you do what everyone does: click a white area, select same fill, delete.

Sometimes the lettering goes with the background and you're left with a navy slab with holes in it. Sometimes you click a letter, the letters go, and the white around the box stays put. Which one you get depends on the file, and the reason is the same either way.

What the trace actually contains

We made the file on purpose so there's nothing hidden in it: a 640×200 navy rectangle (#1b3a6b) with the word KNOCK in white, saved once as PNG and once as JPEG at quality 82. Then traced both with our own tool, Vectorize, and counted the fills.

source what the SVG holds
PNG 1 navy path, 6 paths of #ffffff
JPEG q82 1 path #1b396b, 2 paths #263757, 5 paths #fcffff, 1 path #ffffff

On the PNG, the background and the five letter shapes are all exactly #ffffff. "Select same fill" grabs all six. Delete them and the text is gone with the background.

On the JPEG, compression nudged the white inside the letters to #fcffff, while the big white around the box stayed #ffffff. Now there are two whites that look identical on screen and aren't the same colour. Select same fill on the background and the letters stay. Select it on a letter and the background stays. The navy split too: the two #263757 paths are the darker rim JPEG leaves along the edges.

None of this is a bug in one tracer. A tracer reports the colours that are in the pixels, and the pixels in a JPEG aren't what the designer picked. Illustrator, Inkscape and ours will each show it their own way, but the file is the same file.

What to do instead

  1. Count before you delete. Open the SVG in a text editor, or run grep -oE 'fill="[^"]*"' logo.svg | sort | uniq -c. If you see two near-whites, you have two.
  2. Remove the background as a shape, not a colour. In Vectorize that's --transparent: it drops the background path and leaves every other path alone. On both files above it removed exactly one path, and the five letters survived, PNG and JPEG alike.
  3. Ask for the PNG if you can. It won't stop the letters sharing the background's hex, but it stops the two-whites problem at the source.

What we haven't measured yet: whether the background path is picked by area, by touching the canvas edge, or by position. All three agree on this file. A logo whose white doesn't reach the edge would tell them apart, and we'll update this page when we've traced one.

Reproduce it

Measured on vectorize-cli 0.6.11 (tracer core 0.6.7). The fixture needs ImageMagick; any other way of drawing a navy box with white text works as well.

npm i -g @dudko.dev/vectorize-cli   # or skip the install: https://vectorize.dudko.dev/app/
convert -size 640x200 xc:white -fill '#1b3a6b' -draw 'rectangle 40,30 600,170' \
        -fill white -pointsize 90 -gravity center -annotate +0+0 'KNOCK' wa.png
convert wa.png -quality 82 wa.jpg
vectorize wa.jpg -f svg -o a.svg
vectorize wa.jpg -f svg --transparent -o b.svg
grep -oE 'fill="[^"]*"' a.svg | sort | uniq -c
grep -oE 'fill="[^"]*"' b.svg | sort | uniq -c