Image Format Converter Pipeline: Three Outputs and One White Fill

Most image converters advertise a long input list and hide a short output list. Our format converter does the opposite. The code exposes three output formats, JPEG, PNG, and WebP, and treats everything else as input. This article walks the actual pipeline in the component, including the one branch that decides whether your transparency survives the trip.

What the converter accepts and produces

The file picker accepts anything whose MIME type starts with image/. The drop zone advertises PNG, JPEG, WebP, GIF, BMP, and TIFF as inputs. Output is a separate question. The format options array contains exactly three entries: image/jpeg with a .jpg extension, image/png with .png, and image/webp with .webp.

GIF, BMP, and TIFF are therefore input-only. A GIF converts to a still of its first frame. BMP decodes in every current browser. TIFF is the trap, covered below.

The default output is WebP, and the choice persists in local storage under the key imgconv-output-format. Your last selected format is still active on the next visit, so check that button row before your first conversion of a session.

The pipeline, step by step

Every conversion runs the same five steps in the browser, with no upload:

1. The file becomes an object URL and loads into an Image element.

2. A hidden canvas is sized to naturalWidth and naturalHeight, so pixel dimensions never change during conversion.

3. One branch prepares the background. PNG output gets a clearRect on a fresh canvas. JPEG and WebP output get an opaque white rectangle painted first.

4. The image is drawn on top of that background.

5. canvas.toBlob encodes the result with the chosen type and your quality divided by 100.

Step 3 is the one that surprises people. Because the code paints solid white before drawing for JPEG and WebP, every transparent pixel in your source becomes white in the current build. Alpha survives only when the output is PNG. If you convert a transparent PNG logo to WebP today, you get a white box behind the logo. The in-tool format guide still says WebP supports transparency, and the WebP format itself does, but this implementation flattens it. Treat PNG as the only transparency-preserving output until that branch changes.

The quality slider runs from 10 to 100 with a default of 90, and it disappears when PNG is selected because PNG encoding is lossless and ignores the value.

Size math and the orange warning

After each conversion the tool computes saving as Math.round((1 - result size divided by file size) times 100). A positive number renders green with a minus sign. A negative number renders orange with a plus sign, because the output is larger than the input.

Expect that orange plus sign in specific cases:

  • A photo converted to PNG, because lossless encoding of photographic noise is expensive.
  • An already well-compressed JPEG re-encoded to WebP at quality 90, which can match the source size.
  • Any small image, where container overhead outweighs codec gains.

The format guide inside the tool describes WebP as roughly 30 percent smaller than JPEG. That is a fair planning number for photos at similar quality, and your own files will vary around it. The tool shows both file sizes and the percentage on one line, so check the pair rather than trusting the guide.

Failure modes worth knowing

The catch block does exactly one thing: it stops the spinner. If the Image element fails to decode the file, you get no result and no error message.

That matters most for TIFF. Chromium and Firefox ship no TIFF decoder for the Image element, so a dropped TIFF usually dies silently in those browsers. Convert the TIFF to PNG in an image editor first, then use the tool for the JPEG or WebP step.

Two more limits come from the canvas pipeline itself. Metadata does not survive, because drawing to a canvas rasterizes pixels and nothing else, so EXIF orientation tags and ICC color profiles are gone from every output. And the tool is single-file by construction: the drop handler reads the first file only and the picker has no multiple attribute. One image per run, with no queue.

Checklist before you convert

  • Need transparency in the output? Choose PNG. In this build WebP and JPEG flatten to white.
  • Photo for the web? Choose WebP, keep quality at 90, and read the saving percentage.
  • Tiny source file? Compare both sizes, the orange plus sign appears whenever the output loses.
  • TIFF input? Re-export as PNG before using the tool.
  • Rely on EXIF orientation or a color profile? Re-apply them downstream, the canvas drops both.
  • Converting many files? Budget one run each, batch mode is not implemented in this component.

Run your own file through the converter at /en/format-converter and verify the white-fill behavior on a transparent PNG. Send the same source through the PNG and WebP outputs and compare the two downloads side by side. If your WebP keeps its alpha where this test lost it, the branch has been fixed, this article is out of date, and the file that proves it is welcome here.