Skip to content

Developer tool

Image to Base64, and whether you should.

Drop an image and get a Data URI for CSS, HTML, JSX or a Tailwind config. The file is read in this tab and never uploaded. The part most converters leave out is here too: whether inlining this image is a good idea at all, measured rather than guessed.

Drop an image, or click to choose PNG · JPG · SVG · WebP · AVIF · GIF · ICO

How this works

Your file is read with the browser's FileReader, identified by its first bytes rather than its file name, encoded, and measured with the browser's own gzip. No request is made and nothing is stored.

  • No upload
  • No account
  • No limit but your memory

The other direction

Decode a Data URI.

Paste a Data URI or a bare Base64 string. You get the real format — read from the bytes, not from what the URI claims — the size, a preview, and the file itself.

From a script

There is an API.

The page above never uploads anything, which is the point of it. When the caller is a build step rather than a person, use these instead. No key needed to start: 60 requests an hour by IP, and an API key raises that to 600.

POST /api/image/encode

A file, a url or a data URI in, a Data URI and a recommendation out. Add optimise=true with a width to resize and re-encode first.

curl -F file=@logo.png \
  -F optimise=true -F width=192 \
  https://7azzani.com/api/image/encode

POST /api/image/optimize

The re-encoding on its own, without the Base64 envelope. Returns the winning format's bytes and what each candidate weighed.

POST /api/image/decode

What a Data URI really contains, read from the bytes rather than from what it claims.

GET /api/image/formats

What this server reads and writes, the current limits, and the thresholds the advice uses.

Two differences from the page

It can write AVIF, which canvas.toBlob cannot, so the API often beats the browser by a wide margin on photographs. And it can fetch a url for you — through a guard that refuses loopback, private and cloud-metadata addresses, and re-checks after every redirect.

const r = await fetch('https://7azzani.com/api/image/encode', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ url: 'https://example.com/logo.png',
                         optimise: true, width: 192 })
});
const { output, advice } = await r.json();
// output.data_uri, output.mime, advice.verdict

Worth knowing

Base64 is usually the wrong answer.

It is a useful trick in a narrow band and a liability outside it. These are the numbers behind the advice this tool gives.

The cost

A third larger, then mostly back

Base64 adds exactly 33%. But it encodes into 64 symbols, which a compressor packs well: measured on a photograph, the gzipped cost of encoding was +1.4%, not +33%. Bandwidth is rarely the reason to say no.

The real cost

It stops being a file

A Data URI cannot be cached on its own, so every edit to the CSS re-downloads the image inside it. In a stylesheet it is parsed before the first paint. It can carry neither srcset nor loading="lazy", and it can never be a preload target.

The threshold

About 4 KB

Vite inlines assets under 4,096 bytes; webpack's url-loader used 8,192. Those two numbers are the industry's rough agreement, and this tool reports against them rather than inventing its own.

SVG

Never base64 an SVG

An SVG is text. Base64 costs a flat third; percent-encoding costs only the handful of characters that would end a url() — and the result still compresses, which base64 does not. Measured on a small icon: 214 bytes as base64, 173 percent-encoded, and 208 against 160 once gzipped. This tool builds both and gives you the smaller one.

Email

Don't

Outlook does not render Data URIs at all, and Gmail strips them. In an email, host the image.