Image ↔ Base64

Convert images to Data URI strings or decode Base64 strings to images.

Image to Base64 and data URIs, explained

A data URI packs a whole file into a string that browsers treat like a URL. The format is defined in RFC 2397: data:[media type][;base64],[data]. For a PNG that becomes data:image/png;base64,iVBORw0KGgo..., where everything after the comma is the binary file re-encoded as Base64 text. Because the image travels inside the HTML, CSS, JSON or Markdown that references it, no separate request is needed to fetch it.

This page does the conversion in both directions. Pick an image and the browser reads it with the FileReader API, producing a complete data URI with the media type the browser reports for that file (PNG, JPEG, GIF, WebP, AVIF, SVG or anything else it can decode). Paste a string that starts with data:image into the decode mode and the same image is rendered as a preview. Nothing is uploaded; the bytes stay in the tab.

What Base64 costs you

Base64 represents every 3 bytes of input as 4 characters of output, so an encoded image is about 33% larger than the original file before compression, and a little more once padding is added. A 12 KB icon becomes roughly 16 KB of text. The text also compresses less well than the binary it came from, because the encoding spreads the data over 64 symbols with little repetition, so gzip or brotli recover only part of the difference.

The bigger cost is caching. A regular image is fetched once and then served from the browser cache on every page that references it. An inlined image lives inside the document, so it is downloaded again with every HTML page (or every stylesheet) that carries it, and it cannot be shared between pages at all. Inlining a 200 KB hero photo into three templates means each visitor downloads it three times.

When inlining is the right call

  • Tiny assets that must render on first paint: a 1 to 3 KB logo, a checkbox glyph, a loading spinner.
  • Single-file deliverables: an HTML report, an offline dashboard, or a status page emailed as one .html attachment.
  • Images generated at runtime, for example a chart drawn on a canvas and exported with canvas.toDataURL().
  • Payloads that can only carry text, such as a JSON document or a WebSocket message that has to include a thumbnail.
  • Test fixtures, where committing a data URI string avoids adding a binary file to the repository.

Under HTTP/1.1, saving a request was a strong argument because browsers opened only a handful of connections per host. HTTP/2 and HTTP/3 multiplex many requests over one connection, so that argument is now weak. Decide on caching and size, not on request count.

Using the string in HTML and CSS

<img src="data:image/png;base64,iVBORw0KGgo..." alt="Company logo" width="120" height="40">

.icon-search {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz...");
}

Keep the alt, width and height attributes; a data URI does not change how layout shift or accessibility work. If the site sends a Content Security Policy, the img-src directive must include data:, otherwise the browser refuses to render inlined images and reports a CSP violation in the console.

SVG deserves special treatment

SVG is already text, so Base64 only makes it bigger. For stylesheets you can embed the markup directly with percent-encoding instead: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'...%3E"). Only the characters that are unsafe in a URL (angle brackets, the hash sign, quotes and a few others) need escaping, and the result is smaller and still readable in the source. The Base64 form remains useful when a system requires it, for example an image field that validates the ;base64, marker.

Command-line equivalents

# Linux (GNU coreutils): -w0 disables line wrapping
base64 -w0 logo.png

# macOS
base64 -i logo.png

# Windows PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("logo.png"))

# Node.js
node -e "console.log(require('fs').readFileSync('logo.png').toString('base64'))"

# Python
python3 -c "import base64; print(base64.b64encode(open('logo.png','rb').read()).decode())"

Each of these prints the raw Base64. Add the data:image/png;base64, prefix yourself (with the correct media type) to turn it into a data URI.

Email clients are inconsistent

Some email clients display data URI images and some strip them entirely, so a logo that looks fine in one inbox can vanish in another. Hosted images or CID attachments are the dependable options for HTML email; test in the clients your recipients actually use.

Privacy and safety notes

Encoding is not encryption. Anyone who can read the page can decode the image, and a data URI in a public stylesheet is as public as a hosted file. The conversion here runs entirely in your browser, so screenshots of internal dashboards or unreleased designs never leave your machine. Be aware that browsers block top-level navigation to data: URLs, so a data URI works as an image source but not as a link destination.

How to use

  1. Choose Image to Base64 and click the upload zone to pick a PNG, JPEG, GIF, WebP or SVG file from your computer.
  2. Wait for the preview to appear; the full data URI (media type prefix plus Base64 payload) is shown beside it.
  3. Click Copy String to put the data URI on the clipboard, then paste it into an img src, a CSS url() or a JSON field.
  4. To go the other way, choose Base64 to Image and paste a string that begins with data:image; the decoded picture renders as a preview.
  5. Keep files small. Very large images produce strings that are slow to render in the text box and slow to load on any page that inlines them.

Common use cases

  • Inlining a small logo or icon in a critical CSS block so it paints with the first response.
  • Bundling every image into a single self-contained HTML report that can be emailed or archived.
  • Embedding a chart thumbnail inside a JSON API response or a WebSocket message that can only carry text.
  • Storing a test fixture image as a string in a unit test instead of committing a binary file.
  • Checking what a data URI found in a stylesheet or a log actually contains by decoding it back to a picture.
  • Producing a favicon data URI for a prototype that has no static file hosting yet.

Frequently asked questions

When should I not inline an image?

Skip inlining for anything larger than a few kilobytes or anything used on more than one page. Inlined images bypass the browser cache, so the same bytes are downloaded again with every document that contains them, and they are about 33% larger than the original file.

Which image formats are supported?

Any format the browser itself can read: JPEG, PNG, GIF, WebP, AVIF, SVG and BMP among others. The media type reported by the browser for the file is written into the data URI prefix, for example data:image/webp;base64.

Is my image uploaded to a server?

No. The file is read with the FileReader API inside your browser and the resulting string is kept in the page. You can disconnect from the network after the page loads and the conversion still works.

Why is the Base64 string so much longer than my file size?

Base64 encodes every 3 bytes as 4 printable characters, so the text is about a third larger than the binary. A 30 KB JPEG becomes roughly 40 KB of text before any HTTP compression is applied.

Why does my inlined image not show up on the site?

The most common causes are a Content Security Policy whose img-src directive does not allow data:, a truncated string (copy the whole thing including the prefix), or a wrong media type in the prefix. The browser console reports CSP violations explicitly.

Should I Base64-encode SVG files?

Usually not. SVG is text, so it can be embedded in CSS with percent-encoding and stays smaller and readable. Use Base64 for SVG only when the receiving system insists on the ;base64, form.

Can I decode a data URI back to a file?

Yes. Paste it into Base64 to Image mode to preview it. To save a file, use the command line: strip the prefix up to the comma and pipe the rest through base64 -d on Linux or macOS, or use [Convert]::FromBase64String in PowerShell.

Advertisement