Converting an image to Base64 is one of those tasks developers encounter constantly: embedding a small icon directly in CSS to avoid an HTTP request, attaching an image to a JSON API payload, including a logo in an HTML email, or storing image data in a database field. Base64 encoding turns binary image data into a printable ASCII string that travels safely through text-based protocols.

Convert images to Base64 instantly →

What Is Base64 Image Encoding?

Base64 is an encoding scheme that represents binary data using 64 printable ASCII characters (A–Z, a–z, 0–9, +, /). An image file is binary data — a sequence of bytes representing pixel values, compression tables, and metadata. Base64 converts those bytes into a text string that can be embedded anywhere text is valid.

The trade-off: Base64-encoded data is approximately 33% larger than the original binary. A 100 KB PNG becomes roughly 133 KB as a Base64 string.

Data URI Syntax

The most common use of Base64 images on the web is the data URI scheme:

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

Real-world examples:

<!-- PNG image embedded directly in HTML -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="1px dot">

<!-- SVG icon as data URI in CSS -->
.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDJMMiA3bDEwIDUgMTAtNS0xMC01ek0yIDE3bDEwIDUgMTAtNS0xMC01eiIvPjwvc3ZnPg==");
}

The media type tells the browser how to interpret the data: image/png, image/jpeg, image/svg+xml, image/webp, image/gif.

When to Use Base64 Images

Good use cases

Small icons and logos in CSS: Embedding a 2–3 KB SVG or PNG as a data URI eliminates one HTTP request. For small assets that are used on every page, this can improve perceived performance.

Email HTML templates: Email clients typically block external image requests. Embedding images as Base64 ensures they display without requiring network access or user permission.

JSON API payloads: Some APIs accept images as Base64-encoded strings in JSON request bodies — for example, computer vision APIs, document processing services, or thumbnail upload endpoints.

Offline/self-contained HTML: If you’re building an HTML report or documentation that must work without a network connection, Base64-embedded images ensure all assets travel with the file.

Canvas and WebGL: JavaScript drawImage() and similar APIs work with Base64 data URIs directly.

When NOT to use Base64

Large images: The 33% size overhead is significant for images over 10–20 KB. Use file references instead.

Images used on multiple pages: Base64 images can’t be cached independently by the browser. An external image URL is cached once; the same Base64 string embedded on 10 pages is decoded 10 times.

Performance-critical pages: Parsing large Base64 strings blocks the main thread. External images download in parallel and are decoded off-thread by the browser.

Converting Images to Base64 in Code

JavaScript (Browser)

Reading a file from an <input> element:

const input = document.getElementById('fileInput');

input.addEventListener('change', (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();

  reader.onload = (event) => {
    const base64 = event.target.result;
    // base64 = "data:image/png;base64,iVBORw0KGgo..."
    console.log(base64);

    // Strip the data URI prefix to get just the Base64 string:
    const base64Data = base64.split(',')[1];
    console.log(base64Data);
  };

  reader.readAsDataURL(file);
});

Converting an image URL to Base64 via Canvas:

async function imageUrlToBase64(url) {
  const img = new Image();
  img.crossOrigin = 'anonymous';

  return new Promise((resolve, reject) => {
    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;

      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);

      resolve(canvas.toDataURL('image/png'));
    };
    img.onerror = reject;
    img.src = url;
  });
}

The CORS Pitfall: Tainted Canvas Error

When you draw a cross-origin image onto a canvas and call canvas.toDataURL(), you may encounter:

SecurityError: The operation is insecure.

The browser marks the canvas as “tainted” when it contains pixels from a different origin, blocking toDataURL() to prevent cross-origin data leakage.

Fix 1 — crossOrigin = "anonymous" + server CORS headers

If the image server supports CORS, set crossOrigin before assigning src, and ensure the server responds with Access-Control-Allow-Origin: *:

const img = new Image();
img.crossOrigin = 'anonymous'; // must be set BEFORE .src
img.onload = () => {
  const canvas = document.createElement('canvas');
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  canvas.getContext('2d').drawImage(img, 0, 0);
  console.log(canvas.toDataURL()); // works only if server sends CORS headers
};
img.src = 'https://external-server.com/image.png';

Setting crossOrigin = "anonymous" alone is not enough — the server must also send the Access-Control-Allow-Origin response header.

Fix 2 — fetch() + Blob + FileReader (avoids canvas entirely)

For any server that supports CORS, skip canvas and use fetch() instead:

async function imageUrlToBase64(url) {
  const response = await fetch(url);
  const blob = await response.blob();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(blob);
  });
}

This avoids the tainted-canvas restriction entirely. It works for same-origin URLs and for cross-origin URLs where the server sends CORS headers.

Note: ZeroTool’s image converter uses FileReader on local files — no external requests, no CORS issues.

JavaScript (Node.js)

const fs = require('fs');

// File to Base64
const imageBuffer = fs.readFileSync('./image.png');
const base64 = imageBuffer.toString('base64');
const dataUri = `data:image/png;base64,${base64}`;

console.log(dataUri);

Using the path module to detect media type from extension:

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

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

Python

import base64
from pathlib import Path

def image_to_base64(file_path: str) -> str:
    """Return the Base64-encoded content of an image file."""
    return base64.b64encode(Path(file_path).read_bytes()).decode('utf-8')

def image_to_data_uri(file_path: str, mime_type: str = 'image/png') -> str:
    """Return a data URI suitable for embedding in HTML or CSS."""
    b64 = image_to_base64(file_path)
    return f"data:{mime_type};base64,{b64}"

# Usage
print(image_to_data_uri('logo.png', 'image/png'))

Command Line

# macOS / Linux
base64 -i image.png
base64 -i image.png | tr -d '\n'  # single line, no wrapping

# Create a data URI
echo "data:image/png;base64,$(base64 -i image.png | tr -d '\n')"

Working with the Base64 String

Decoding Base64 Back to an Image

// Node.js: Base64 string → file
const fs = require('fs');

const base64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA...';
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync('output.png', buffer);
# Python: Base64 string → file
import base64
from pathlib import Path

base64_data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...'
Path('output.png').write_bytes(base64.b64decode(base64_data))

Stripping or Adding the Data URI Prefix

// Add prefix
const withPrefix = `data:image/png;base64,${base64String}`;

// Strip prefix
const withoutPrefix = dataUri.replace(/^data:image\/\w+;base64,/, '');

Common Use Case: Sending Images to an API

Many computer vision APIs (OpenAI Vision, Google Cloud Vision, AWS Rekognition) accept Base64-encoded images:

import base64
import httpx

with open('photo.jpg', 'rb') as f:
    image_b64 = base64.b64encode(f.read()).decode('utf-8')

response = httpx.post(
    'https://api.example.com/analyze',
    json={
        'image': {
            'type': 'base64',
            'media_type': 'image/jpeg',
            'data': image_b64,
        }
    }
)

Image Format Reference

FormatMIME TypeBest ForBase64 Use
PNGimage/pngIcons, screenshots, logosCommon
JPEGimage/jpegPhotosLess common (large)
SVGimage/svg+xmlVector icons, logosVery common
WebPimage/webpPhotos with better compressionGrowing
GIFimage/gifAnimated imagesRare
ICOimage/x-iconFaviconsCommon

SVG files deserve special mention: because SVG is XML (text), you can also embed SVG without Base64 encoding by URL-encoding the raw SVG string. This avoids the 33% size overhead:

/* Base64 approach */
background-image: url("data:image/svg+xml;base64,PHN2Zy4uLg==");

/* URL-encoded approach (smaller, more readable) */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'...%3E%3C/svg%3E");

Online Image to Base64 Converter

For quick conversions without writing code, ZeroTool’s Image to Base64 converter runs entirely in your browser. Drag and drop or select any image file and get the Base64 string or data URI immediately. No file is uploaded to any server.

Try the Image to Base64 converter →