Skip to content

Image to Base64

Drop an image or click to browse

Runs in your browser — nothing is uploaded.

Estimates for educational purposes — not financial, medical, or legal advice. See terms.

A base64 data URI lets you embed an image directly inside an HTML file, CSS rule, or Markdown document without referencing an external file. Useful when you can’t host assets separately (email templates, single-file deliverables, build-time SVGs) — but counterproductive for anything bigger than a few KB, since base64 inflates the payload and bypasses normal browser caching.

How encoding works

FileReader.readAsDataURL reads the file’s bytes and produces a string of the form data:image/png;base64,<encoded>. The MIME type comes from the file’s reported type (or sniffed by the browser), and the base64 payload encodes the file’s bytes one-to-one — atob(payload) recovers the original binary exactly.

Encoded length is always exactly ceil(bytes / 3) * 4 characters of base64, plus the prefix. So a 9 KB PNG becomes a ~12 KB string. Plus quoting overhead and the line wrapping in your source file.

Example: small icon for an HTML email

A 2 KB PNG company logo, encoded with the HTML img wrap, becomes a ~2.7 KB <img> tag with alt text. Paste it into an HTML email template (where many clients block external images) and the logo always renders.

Example: CSS background

A small repeating pattern image (say, 800-byte JPEG of paper texture) encoded as background-image: url("..."); becomes a ~1.1 KB CSS rule. No extra HTTP request, no separate file to deploy alongside the stylesheet. Trade-off: the rule is now bigger and slightly harder to scan.

Example: SVG vs base64

An 800-byte SVG icon. Base64 wraps it to ~1.1 KB. URL-encoded (data:image/svg+xml;utf8,...) is closer to 900 bytes and equally-well supported. For SVG specifically, prefer URL-encoding or just inline the <svg> markup directly. The tool will base64-encode SVG on request — useful as a baseline — but the URL-encoded form is shorter.

When base64 is the wrong choice

  • Big images. A 200 KB JPG becomes a 270 KB string. Now every page that uses it ships those 270 KB inside the HTML/CSS, with no separate caching. Hosting + linking is faster.
  • Images on more than one page. Browsers cache files at their URL. A base64-embedded image is re-downloaded on every page; a hosted image downloaded once and reused.
  • Images that change. Editing an embedded image means re-encoding and re-pasting into every file that uses it. Hosted images can be swapped at the URL.

Common mistakes

Confusing base64 with encryption. Base64 is encoding, not encryption. The bytes are recoverable by anyone with atob(). Don’t put secrets in a data URI thinking they’re hidden.

Forgetting the MIME type. A data URI with no image/... prefix won’t render. The tool always emits the prefix correctly; if you’re hand-rolling somewhere else, make sure the MIME type matches the actual file format.

Padding-stripped base64. Some tools emit base64 with the trailing = padding stripped (URL-safe variant). Standard data URIs include the padding. The tool emits standard form.

Embedding everywhere by reflex. “Avoid HTTP requests” was the right advice in 2010 over HTTP/1.1 with limited concurrency. On HTTP/2 and HTTP/3 with multiplexing, the cost of a separate request is much lower, while the cost of inflated HTML/CSS payloads is just as high.

Trusting reported KB/MB sizes as universal. macOS reports decimal sizes (1 KB = 1000 bytes); Windows reports binary sizes (1024 bytes) under the same KB label. Same file, slightly different number depending on whose ruler you use — see the explainer on MB vs MiB.

What this tool does not do

It doesn’t upload anywhere. The browser’s FileReader does the encoding locally.

It doesn’t resize, compress, or convert formats. See the image resizer, image compressor, and image format converter for those.

It doesn’t decode base64 back to a file. Browser image elements decode automatically when the data URI is set as src.

It doesn’t batch-encode multiple files. One file per session — base64 embedding is rarely a workflow you want to batch.

Frequently asked questions

When should I embed an image as base64 instead of linking to it?

When the image is tiny (under ~10 KB) and one of: you can't host static assets (single-file HTML email templates, embedded markdown), you want to avoid an extra HTTP request, or the asset is a data fingerprint that needs to travel with the document. For anything bigger than ~50 KB, link to a hosted file — base64 inflates the payload by ~33% and bypasses browser image caching, so the same image loaded on multiple pages is downloaded fresh each time.

Why does encoded base64 take more space than the original file?

Because base64 uses 64 characters (A-Z, a-z, 0-9, +, /) to represent every 6 bits of binary, and ASCII characters are themselves 8 bits. So 3 bytes of binary become 4 characters of base64 — exactly 33% overhead. Plus the data URI prefix `data:image/png;base64,` adds another ~25 bytes on top. The tool shows both source and encoded sizes so you can see the inflation.

What's the size warning above 100 KB about?

100 KB is the rough community guideline above which base64 embedding becomes counterproductive. Reasons: HTML/CSS files balloon (browsers parse them eagerly and synchronously), the asset is downloaded on every page that references it (no browser-level cache benefit), gzip helps less than you'd expect (base64 has poor compressibility because of its character distribution). At that size, a `<link rel=preload>` to the actual file is almost always faster, and the extra HTTP request is one round-trip — not a big deal on HTTP/2 or HTTP/3.

Does this work with SVG files?

Yes — SVG counts as an image type, so the tool encodes it. But SVG is text already, so base64 is wasteful overhead. For SVG, prefer URL-encoded data URIs (`data:image/svg+xml;utf8,<svg ...>`) or just inline the SVG markup directly into your HTML/CSS. The tool will produce a base64-encoded SVG if you ask, but flag it: the URL-encoded form is shorter and equally well-supported.

Why are there four output formats?

Because the same data URI fits four different embedding contexts and each wants the URI in a slightly different wrapper. **Data URI** — bare string, paste anywhere that wants `data:...`. **HTML img** — `<img src=...>` ready to drop into HTML. **CSS bg** — `background-image: url(...);` for stylesheets. **Markdown** — `![alt](data:...)` for prose. The encoded data is identical across all four; only the surrounding syntax differs. Pick the format that matches where you're pasting.