Base64 to Image Converter
Paste Base64 or a data: URI and see the image instantly — or turn an image file into copy-ready Base64 snippets, on this device.
Snippet form shapes the Image → Base64 output — switch tabs to use it.
The decoded image appears here — preview, size and download.
Press ? for shortcuts
Do it offline:$ base64 -d image.b64 > image.png
How to use it
- Paste Base64 into the decode tab — bare, wrapped across lines, or a whole data: URI copied out of a src attribute. Decoding runs as you type, and every tolerance applied on the way (ignored whitespace, URL-safe characters, restored padding) is announced as a chip, never applied silently.
- Read the preview card: the image renders from its sniffed type, the meta row prints raw size, Base64 length, overhead and pixel dimensions, and Download saves the file under the extension the bytes deserve.
- For the other direction, open the Image → Base64 tab and drop a file or use the picker. Pick the output form — Base64, data URI, <img> tag or CSS url() — and copy it; the form choice is remembered on this device.
- Share turns the decode-tab state into a link fragment that never reaches a server. On the encode tab a share carries the settings only — file bytes stay on your machine, and the note under Share says so.
Paste Base64 or a complete data: URI and the picture appears at once — typed by its real bytes, measured, and downloadable under the extension its signature earns. Switch tabs to go the other way: drop an image file and collect four copy-ready artifacts — raw Base64, a data: URI, an <img> tag, a CSS url() rule. Conversion runs entirely in your browser; no picture is uploaded, logged, or kept.
How it works
A data: URI is a miniature transport format defined by RFC 2397: after the scheme comes an optional mediatype, an optional ;base64 flag, then a comma and the payload. With the flag, the payload is Base64; without it, the payload is percent-encoded text — the form hand-written SVG snippets usually take. This page parses that grammar first, fills in the RFC's default mediatype when the URI omits one, and routes the payload to the matching decoder, so both payload forms end as bytes.
The declared mediatype is treated as a claim, nothing more. Raster formats open with fixed signatures — PNG begins 89 50 4E 47 0D 0A 1A 0A, JPEG begins FF D8 FF, GIF begins 47 49 46 38 — so the decoded bytes are checked against a signature table, plus a small heuristic that recognizes SVG markup. That sniffed type drives everything you see: the preview, the type badge, the download extension. When the label and the signature disagree, a warning chip says so and the bytes win.
The preview never re-encodes anything. The decoded bytes are wrapped in a Blob typed with the sniffed MIME, handed a short-lived object URL, and rendered by an ordinary <img> element — the same path the browser takes for any picture. That rendering context is also the safety property: an SVG referenced from <img> runs under the SVG Integration spec's secure static mode, where script never executes and external references are never fetched. Old object URLs are revoked as soon as a new preview replaces them.
Encoding is the same walk in reverse. The file's bytes are read once, sniffed for their real type, and expanded through the RFC 4648 alphabet — every 3 bytes become 4 characters, which is exactly where the +33% size overhead comes from, plus a little rounding when padding fills the final group. The data: URI, the <img> tag and the CSS rule are all assembled around that single encoding, so the four artifacts can never drift apart.
Examples
data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7image/gif — 42 bytes → 56 Base64 characters (+33%) · 1 × 1 px · Download .gifA complete 42-byte GIF — about the smallest picture worth testing with. Declared and sniffed types agree, and the size line is plain arithmetic: 42 bytes need 56 Base64 characters, a 33% expansion.
sample.gif (42 bytes — the 1 × 1 GIF from the first example)R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="">
background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");The same pixel back through the encode tab: one encoding feeds all four forms, so the payload inside every artifact is character-for-character identical — only the packaging differs.
data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7The data: URI declares image/png, but the bytes carry a image/gif signature. The preview and download trust the bytes.The edge case: a label that lies. The output above is the engine's warning chip, word for word, and everything visible follows the bytes — the preview renders a GIF and the download is named .gif. Mislabelled URIs usually come from a pipeline that renamed files without converting them.
data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%221%22%20height%3D%221%22%2F%3Eimage/svg+xml — 62 bytes from a percent-encoded payload · Download .svgNo ;base64 flag, so everything after the comma is percent-encoded — the norm for SVG because the XML stays almost readable. Each %XX escape becomes one byte, exactly as the WHATWG data: URL algorithm prescribes, and the sniffer recognizes the markup as SVG.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Percent-encoded payloads are not URL query strings
RFC 2397's second payload form reuses percent escapes, but the resemblance to form encoding ends there: %3C becomes the single byte 0x3C, while + stays a literal plus instead of turning into a space. A truncated escape — a % with fewer than two hex digits behind it, typical of an attribute value cut mid-copy — fails with a position-anchored error rather than a guess.
Base64 wrapped by CSS, email or an editor still decodes
Payloads copied out of stylesheets and MIME bodies arrive with line breaks and indentation, sometimes minus their = padding or in the URL-safe alphabet. Every repair is reported as its own chip — whitespace skipped, padding restored, - and _ translated — and the size figures are computed from the canonical encoding, so the overhead number never lies about the wrapping.
SVG previews are script-inert by construction
An SVG file can carry script elements, event handlers and external references, so this page only ever shows one through an <img> element and never injects the markup into the document. In that context browsers apply secure static mode: scripting is off and external resources are not loaded. You see the artwork; the code inside the payload never runs.
data:, is a legal URI that decodes to nothing
RFC 2397 lets both the mediatype and the payload be omitted, so the six characters data:, form the shortest legal data URI, with text/plain as its defaulted type. A zero-byte payload lands as a calm empty state here — no error banner, and no mismatch warning either, because zero bytes carry no signature to disagree with.
Non-image bytes get named, not guessed at
Feed this page a Base64-wrapped PDF and the warning tells you precisely that — detected: application/pdf — while the download keeps working under the honest extension. ZIP and GZIP archives, fonts and media containers are recognized the same way; bytes matching no signature fall back to application/octet-stream, and HEIC lands in the generic ISO-media bucket its ftyp box announces. Nothing is previewed unless the bytes are an image.
Common errors
Invalid Base64: character '"' at position 57- The classic HTML-copy accident: selecting a src attribute grabs its closing quote along with the payload. The error names the exact position and the input stays untouched, so deleting that one character fixes it — and pasting the attribute's whole value, data:image/… prefix included, is fine, because the prefix is parsed rather than refused.
Percent escape '%2' at position 26 is incomplete — '%' must be followed by two hexadecimal digits. Write a literal percent sign as %25.- A percent escape is exactly a % followed by two hex digits, and this payload stops mid-escape — almost always a URI truncated in transit: a log line cut at a column limit, or a selection that missed the tail. Recover the full attribute value instead of trimming the broken escape.
The data: URI declares image/png, but the bytes carry a image/gif signature. The preview and download trust the bytes.- A warning rather than a refusal: the image still previews and downloads, driven by its signature. The label usually drifts when an export step renames files without converting them, or when a URI was assembled by hand around the wrong mediatype. Correct the label before shipping it to consumers that trust declarations.
Input is larger than the 16 MB limit for this tool. For bigger payloads use the CLI: base64 -d image.b64 > image.png- The cap is a refusal, never a truncation — nothing is trimmed and nothing is uploaded to get around it. The command line has no such ceiling; on BSD systems where the file argument is rejected, the stdin spelling base64 -d < image.b64 > image.png does the same decode.
FAQ
Why won't my Base64 image display?
Usually one of three causes. The payload was truncated — Base64 whose length lands one character past a multiple of four cannot have come from an encoder, and the error says where it broke. A character outside the alphabet rode along, typically a quote or bracket picked up while copying markup. Or the bytes are simply not an image, in which case the warning prints what the signature table found instead. And when a declared label contradicts the signature, this page follows the signature — a browser handed the same URI believes the label and may show a broken-image glyph.
How do I embed a Base64 image in HTML or CSS?
Copy the <img> form for markup or the CSS url() form for a stylesheet — both package the same data: URI inside quotes so the payload characters survive. The generated tag carries alt="" deliberately: an empty alt declares an image decorative to screen readers, which is only correct when it truly is. If the picture carries meaning, replace the empty string with real alt text before the tag ships.
Should I embed images as Base64 instead of linking to files?
Measure first. The encoding itself costs one third — 4 output characters for every 3 input bytes, the +33% this page computes live — and an embedded image cannot be cached separately, so every copy of the carrying document downloads the pixels again. Embedding wins where a request costs more than the extra bytes: small icons, email HTML, self-contained documents. There is no universal size cutoff; the meta row gives you the real numbers for your image.
Is it safe to preview an SVG data URI here?
The preview cannot execute what the SVG carries. It renders through an <img> element, and browsers apply the SVG Integration spec's secure static mode to that context: script is disabled, external references stay unfetched, interactivity is off. The markup itself is never injected into this page's document — and decoding happens locally, so the URI you paste is not sent anywhere.
Which image formats does this tool detect?
PNG, JPEG, GIF, WebP, AVIF, BMP and ICO are recognized by their byte signatures, and SVG by a markup heuristic; all of them preview inline. Other recognizable types — PDF, ZIP, GZIP, fonts, audio and video containers — are named in a warning and offered as a download only. Bytes that match nothing are labelled application/octet-stream honestly rather than guessed at.
How do I convert a PNG or JPG to Base64 with this page?
That direction is built in: switch to the Image → Base64 tab, drop the file or pick it, and copy whichever artifact you need — dropping an image file anywhere on the page switches to that tab for you. The MIME type inside the generated URI comes from the file's bytes, never its filename. On a shell, GNU coreutils does the raw encoding with base64 -w 0 photo.png; this page adds the sniffing, the snippets and the size math.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Run the conversion now — inputs above the auto-run band wait for this.
- ⌘/Ctrl + S
- Download the result: the decoded image file on the decode tab, the active snippet as .txt on the encode tab.
- ⌘/Ctrl + C
- With nothing selected, copy the artifact — the normalized data: URI when decoding, the active snippet when encoding.
- ⌘/Ctrl + Shift + C
- Copy the artifact even while text is selected.
- ? or ⌘/Ctrl + /
- Open the shortcut help overlay.
- Esc
- Close the topmost dialog — the input is never cleared.
- t
- Cycle the color theme (outside text fields).