Base64 Image Encoding — Data URIs for HTML & CSS

A Base64 data URI embeds image data directly in HTML or CSS — no separate file, no extra HTTP request. The format is data:image/png;base64,.... It's ideal for small assets, but has important performance tradeoffs to understand.

Drop an image here or click to browse
PNG · JPG · GIF · SVG · WebP · AVIF — runs locally, never uploaded
Preview of the converted image
DATA URI
Waiting for an image

Need a dedicated converter? Use Image to Base64 (any format), PNG to Base64, JPG to Base64, or SVG to Base64 — or go the other way with Base64 to Image.

The Data URI Format

data:[mediatype][;base64],[data]

Examples:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv...
data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEK...
data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgA...

Using Data URIs in HTML

<!-- In an img tag -->
<img src="data:image/png;base64,iVBORw0KGgo..." alt="Logo" width="32" height="32">

<!-- In an SVG -->
<image href="data:image/png;base64,iVBORw0KGgo..." width="100" height="100"/>

<!-- In a link (favicon) -->
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4...">

Using Data URIs in CSS

/* Background image */
.logo {
  background-image: url('data:image/png;base64,iVBORw0KGgo...');
  width: 32px;
  height: 32px;
  background-size: contain;
}

/* Cursor */
.custom-cursor {
  cursor: url('data:image/png;base64,...') 8 8, auto;
}

/* CSS content property */
.icon::before {
  content: url('data:image/svg+xml;base64,...');
}

Real-World Examples

Email signature logo

Email clients frequently block external images until the reader clicks "show images," which hides a hosted logo. A Base64 data URI renders immediately in most clients (Outlook for Windows is the notable exception):

<table>
  <tr>
    <td><img src="data:image/png;base64,iVBORw0KGgo..." width="48" height="48" alt="Acme"></td>
    <td style="padding-left:12px">
      <strong>Jane Doe</strong><br>Acme Inc.
    </td>
  </tr>
</table>

CSS loading spinner

A tiny inline SVG or GIF spinner shows instantly with zero network round-trip — handy for skeleton states and above-the-fold loaders that must appear before any other asset arrives:

.spinner {
  width: 24px;
  height: 24px;
  background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...') no-repeat center;
  background-size: contain;
}

Repeating background texture

A small tile (a few hundred bytes) inlined as a data URI covers an entire element via repeat with no separate request:

.noise {
  background-image: url('data:image/png;base64,iVBORw0KGgo...');
  background-repeat: repeat;
}

Generating Data URIs

In the Browser (JavaScript)

// From a File object (e.g., file input or drag-drop)
function imageToDataURI(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = e => resolve(e.target.result); // Full data URI
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// From a canvas
const canvas = document.getElementById('myCanvas');
const dataURI = canvas.toDataURL('image/png');         // PNG
const jpegURI = canvas.toDataURL('image/jpeg', 0.9);   // JPEG at 90% quality

// From an img element
function imgToDataURI(imgElement) {
  const canvas = document.createElement('canvas');
  canvas.width = imgElement.naturalWidth;
  canvas.height = imgElement.naturalHeight;
  canvas.getContext('2d').drawImage(imgElement, 0, 0);
  return canvas.toDataURL();
}

In Python

import base64, mimetypes

def image_to_data_uri(path: str) -> str:
    mime = mimetypes.guess_type(path)[0] or 'image/png'
    with open(path, 'rb') as f:
        encoded = base64.b64encode(f.read()).decode('ascii')
    return f"data:{mime};base64,{encoded}"

print(image_to_data_uri('logo.png')[:60])
# data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...

In Node.js

const fs = require('fs');
const path = require('path');

function imageToDataURI(filePath) {
  const ext = path.extname(filePath).slice(1).toLowerCase();
  const mimeMap = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',
                    gif: 'image/gif', svg: 'image/svg+xml', webp: 'image/webp' };
  const mime = mimeMap[ext] || 'image/png';
  const base64 = fs.readFileSync(filePath).toString('base64');
  return `data:${mime};base64,${base64}`;
}

Decoding: Base64 Back to an Image

Going the other way — turning a data URI or raw Base64 string back into a viewable, downloadable image — is just as common. The simplest case needs no code at all: paste the full data URI straight into an <img> and the browser decodes and renders it.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="decoded">

In the Browser (JavaScript)

// Data URI -> Blob -> object URL (works for downloads too)
async function dataURIToBlobURL(dataURI) {
  const res = await fetch(dataURI);   // fetch handles the decode
  const blob = await res.blob();
  return URL.createObjectURL(blob);   // assign to img.src or an 
}

// Raw Base64 (no data: prefix) -> bytes
function base64ToBytes(b64) {
  const bin = atob(b64);
  const bytes = new Uint8Array(bin.length);
  for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
  return bytes; // wrap in new Blob([bytes], { type: 'image/png' })
}

In Python

import base64

# Strip the data: prefix if present, then decode to real bytes
raw = data_uri.split(',', 1)[-1]
with open('out.png', 'wb') as f:
    f.write(base64.b64decode(raw))

Prefer a no-code path? Drop your string into Base64 to Image (or Base64 to PNG) to preview and download the file instantly.

How Much Bigger? The 33% Overhead

Base64 represents every 3 bytes of binary data as 4 ASCII characters, so the encoded text is always about 33% larger than the original file (plus up to 2 padding characters and, for data URIs, the short data:image/…;base64, prefix). That overhead is the core reason to reserve Base64 for small assets:

Original imageAs Base64 (~+33%)Verdict
0.5 KB icon~0.7 KB✅ Inline it
2 KB logo~2.7 KB✅ Usually fine
12 KB PNG~16 KB⚠️ Borderline
100 KB photo~133 KB❌ Keep as a file
1 MB hero image~1.33 MB❌ Never inline

The overhead compounds: inlined images bloat your HTML/CSS, which is render-blocking and can't be cached separately — every byte re-downloads whenever the containing file changes. For a single tiny icon that saves one request, it's a win; for anything reused across pages, a normal <img src="photo.jpg"> with cache headers is faster.

When to Use Base64 Images

Good use cases:

  • Small icons and favicons (< 2KB)
  • Inline SVG logos that need to be embeddable
  • Images in emails (many email clients block external images)
  • Single-file HTML pages or offline apps
  • Critical above-the-fold images to eliminate render-blocking requests

Avoid for:

  • Large images (> 5KB) — the ~33% size overhead hurts significantly
  • Images used on multiple pages — they can't be browser-cached separately
  • Images that change frequently — embedded data URIs require re-deploying HTML/CSS

SVG as Base64 vs Inline SVG

For SVG images specifically, inline SVG is usually better than Base64:

<!-- Base64 SVG (larger, can't be styled with CSS) -->
<img src="data:image/svg+xml;base64,PHN2Zy...">

<!-- Inline SVG (smaller, styleable, accessible) -->
<svg viewBox="0 0 24 24"><path d="M12 2..."></svg>

<!-- URL-encoded SVG in CSS (no Base64 overhead for simple SVGs) -->
background-image: url("data:image/svg+xml,%3Csvg...");

Frequently Asked Questions

How do I convert an image to Base64?

Drop your image into the converter at the top of this page and copy the data URI it produces. In code, use FileReader.readAsDataURL() in the browser, base64.b64encode(...) in Python, or Buffer.from(...).toString('base64') in Node.js.

How do I decode a Base64 string back to an image?

Put the full data URI (data:image/png;base64,...) directly in an <img> src and the browser renders it. To recover a real file, decode with atob() in JavaScript or base64.b64decode() in Python, or use the Base64 to Image tool.

How much bigger is a Base64 image?

About 33% larger than the original binary — Base64 encodes every 3 bytes as 4 characters, so a 12 KB PNG becomes roughly 16 KB of text. See the size table above for common cases.

Why is my Base64 image not showing?

The three usual causes: a wrong or missing MIME type (use data:image/png for a PNG), a truncated or line-wrapped string (it must be one unbroken sequence), or bad padding (length must be a multiple of 4, padded with =). Confirm the full data: prefix is present too.

Can I use Base64 images in email?

Yes for most clients, and it avoids the external-image blocking that hides normal <img src> images. The main exception is Outlook on Windows, which won't render Base64 data URIs — test there or fall back to a hosted image.

Convert your image to Base64 now

Use the drop-zone converter at the top of this page, or open the full base64.dev tool for text, files, and URL-safe mode.

Open base64.dev →