Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To display a data URL as an image in JavaScript, assign the complete URL to an HTMLImageElement‘s src and wait for it to load. You do not need to decode it into a Blob or pass it through a canvas just to show it. Use a Blob when an API needs binary image data, and use a canvas when you need to read pixels or transform the image.

Display a data URL as an image

A data URL is already a resource URL. The browser can load it directly into an image element. Wait for the load event before appending the image or reading its dimensions; otherwise, those dimensions may not be available yet.

function loadImage(dataUrl) {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = () => reject(new Error("Could not load image data URL"));
    image.src = dataUrl;
  });
}

const image = await loadImage(dataUrl);
document.body.append(image);
console.log(image.naturalWidth, image.naturalHeight);

This example uses top-level await, which is valid in a JavaScript module. In a regular script, put the last three lines inside an async function or use an async event handler:

async function showImage(dataUrl) {
  const image = await loadImage(dataUrl);
  document.body.append(image);
  return image;
}

The image object can be used in the DOM without an intermediate canvas or object URL. Use naturalWidth and naturalHeight for the source image’s intrinsic dimensions; CSS sizing can change how large it appears on screen without changing those values.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the data URL format

A data URL has this general form: data:[<media-type>][;base64],<data>. The comma separates the metadata from the payload. For an image, the media type should identify the format, such as image/png or image/jpeg. If the media type is omitted, the default is text/plain;charset=US-ASCII, not an image format. The ;base64 marker indicates that the payload is Base64-encoded; without that marker, the payload uses URL-encoded data. See MDN’s data: URLs documentation.

  • Confirm the value begins with data: and contains a comma.
  • Check that the declared MIME type matches the actual image data.
  • Check whether the payload is Base64 or URL-encoded, and make sure the prefix reflects that encoding.
  • Pass the entire data URL to image.src, not just the part after the comma.

For example, a PNG data URL generally starts with data:image/png;base64,. A JPEG should declare image/jpeg. The prefix describes the payload; it does not turn arbitrary text or bytes into a valid image. MDN’s Canvas API guide also demonstrates using a data URL directly as an image source: Using images — Canvas API.

Choose the right representation for the job

What you need Use Why
Show the image in a page Image.src = dataUrl The data URL is already an image resource URL; no conversion step is needed.
Give an API binary image data Blob A Blob represents the image bytes in a form many browser APIs can consume.
Display a Blob-backed image URL.createObjectURL(blob) An object URL points to the local Blob without putting its encoded contents into a URL string.
Read pixels, draw, resize, or re-encode canvas Canvas provides drawing and pixel-processing operations; it is unnecessary for display alone.

These are different representations, not competing ways to make the browser recognize an image. Prefer the least complex option that meets the next step in your application.

Convert a data URL to a Blob

If a later operation needs a Blob, the browser can read a data URL as a fetch response and expose the response body as a Blob:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
async function dataUrlToBlob(dataUrl) {
  const response = await fetch(dataUrl);
  return response.blob();
}

const blob = await dataUrlToBlob(dataUrl);
console.log(blob.type, blob.size);

This avoids manually splitting the data URL and decoding its payload. The returned Blob’s type reflects the media type, if one was provided, and size is its byte length. If you need to display the Blob, create an object URL:

const blob = await dataUrlToBlob(dataUrl);
const objectUrl = URL.createObjectURL(blob);
const image = new Image();

image.onload = () => {
  document.body.append(image);
};
image.onerror = () => {
  URL.revokeObjectURL(objectUrl);
  console.error("Could not load Blob image");
};
image.src = objectUrl;

// Revoke objectUrl after the image and any feature that uses it are finished.

Do not revoke the object URL immediately after setting src. The image may still need it for rendering, opening, or saving. Revoke it when the image is removed and no remaining interaction depends on the URL. MDN explains the lifecycle in its blob: URLs documentation.

Use canvas to read pixels or export a new image

Canvas is appropriate when you need to inspect pixel values, draw the source into another image, resize it, or encode a transformed result. Load the image first, then draw it at its intrinsic size:

const image = await loadImage(dataUrl);
const canvas = document.createElement("canvas");
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;

const context = canvas.getContext("2d");
if (!context) throw new Error("Could not create a 2D canvas context");
context.drawImage(image, 0, 0);

const pixels = context.getImageData(0, 0, canvas.width, canvas.height);
console.log(pixels.width, pixels.height, pixels.data);

getImageData() returns pixel data, typically in an array with red, green, blue, and alpha values for each pixel. Canvas dimensions should be set before drawing. Setting them clears the canvas, so set them before calling drawImage().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To export the canvas as a Blob, use toBlob() rather than building a large data URL when you do not specifically need a serialized string:

function canvasToBlob(canvas, type = "image/png") {
  return new Promise((resolve, reject) => {
    canvas.toBlob(blob => {
      if (blob) resolve(blob);
      else reject(new Error("Image export failed"));
    }, type);
  });
}

const outputBlob = await canvasToBlob(canvas, "image/png");
const outputUrl = URL.createObjectURL(outputBlob);

const resultImage = new Image();
resultImage.src = outputUrl;
resultImage.onload = () => document.body.append(resultImage);
// Revoke outputUrl after the result image is no longer needed.

Canvas export can fall back to PNG if the requested format is unsupported. Check the resulting Blob when the exact output format matters. toDataURL() is useful when a caller explicitly requires a data URL or the image is small, but it creates the complete encoded image as an in-memory string. For large images, that can consume substantial memory and may exceed browser URL length limits. MDN documents the trade-offs for HTMLCanvasElement.toDataURL(); the WHATWG HTML Standard’s canvas section describes canvas export behavior.

Understand canvas security before processing remote images

An image displaying successfully does not guarantee that JavaScript can read its pixels. If you draw a cross-origin image onto a canvas without the remote server permitting cross-origin access, the canvas becomes tainted. Pixel access and exports such as getImageData(), toBlob(), and toDataURL() can then throw a SecurityError. The image server must send appropriate CORS permission for the canvas to remain readable. See the WHATWG canvas element rules and MDN’s guide to using cross-origin images in a canvas.

Data URLs are inline resources, but modern browsers treat them as unique opaque origins. Do not assume a data URL inherits the origin of the document that created it. That origin behavior is separate from the basic display operation: assigning a valid data URL to Image.src does not require a canvas. MDN covers this in its data: URL reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot a data URL that will not load

Symptom Likely cause What to check
image.onerror fires Malformed URL, invalid payload, or unsupported/non-image content. Check the comma, image MIME type, and encoding marker. Verify that the payload actually represents an image.
The URL is treated like text rather than an image The media type is missing or is not an image type. Declare the correct type, such as image/png or image/jpeg.
The image appears, but dimensions are zero or unavailable Code read the dimensions before loading completed. Wait for onload or decode() before checking naturalWidth and naturalHeight.
Canvas drawing works, but pixel access or export fails The canvas is tainted by a cross-origin image. Ensure the image host permits CORS; displaying an image alone does not grant pixel access.
Exporting a large image makes the page memory-heavy toDataURL() serializes the full image into a string. Use toBlob() and an object URL unless a data URL string is specifically required.
A Blob-backed image stops working unexpectedly Its object URL was revoked while still in use. Keep the URL alive for the image’s needed lifetime, then call URL.revokeObjectURL().

For debugging, first log the prefix up to the comma rather than dumping a potentially huge image string. Then confirm that the URL is complete and that the payload came from a real image. An onerror handler provides a useful failure branch, but it does not identify which part of the data URL is wrong.

Or skip the browser setup

If your actual goal is to capture a webpage as an image rather than display or transform an existing data URL, ScreenshotNeo offers a screenshot API. It takes a webpage URL and returns a screenshot; it is not a converter for an arbitrary data URL.

cURL example, with the target URL set to Stripe:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets can be removed before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

Frequently Asked Questions

Does assigning a data URL to an image re-encode or optimize it?

No. Setting image.src loads the image for display; it does not resize, recompress, or create a newly encoded image. Use canvas when you need to transform or export a new image.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use an image’s displayed width or its natural width for a canvas?

For a canvas that should contain the source image at its intrinsic size, use naturalWidth and naturalHeight. CSS can change displayed dimensions without changing the image’s intrinsic dimensions.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.