Free tools Windows power users keep installed

One-click scans. No signup required.

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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To save the pixels inside a canvas, call canvas.toBlob() (recommended for files) or canvas.toDataURL(). To capture how a canvas looks as part of a rendered page or element, use a browser screenshot tool such as Playwright. These are different jobs: canvas export reads the bitmap, while a browser screenshot records rendered pixels. If a canvas contains cross-origin content without the required CORS permission, direct export can fail with a SecurityError.

Choose between exporting the canvas and screenshotting it

First decide what the output needs to contain. A canvas export gives you the canvas bitmap by itself. A browser screenshot captures the canvas as it appears in the page, and can include surrounding DOM content when you capture a larger region.

What you need Use Result
The canvas pixels as an image file or Blob canvas.toBlob() A Blob, usually suitable for download, upload, or further processing
The canvas pixels as a string canvas.toDataURL() A data URL, commonly used as an image source
The canvas as displayed in a web page Playwright page or locator screenshot Screenshot bytes or an image file, with the option to capture a page or one element
A canvas plus nearby interface elements Playwright page screenshot or screenshot of a containing element A rendered view that includes the selected page or region

Prefer toBlob() when creating a file: it avoids placing the entire image in a potentially large data URL string. Choose a browser screenshot when you need the rendered appearance, not just the canvas bitmap. Neither method should be treated as a general way to read pixels that browser security rules prohibit your page from accessing.

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

Save a canvas as a PNG with JavaScript

Call toBlob() on the canvas after it has been drawn. It is asynchronous: the image is delivered to a callback, which may receive null if the browser could not create the requested Blob. The default and required format is PNG; if you omit the type, or request an unsupported type, the browser uses PNG.

const canvas = document.querySelector('canvas');

if (!(canvas instanceof HTMLCanvasElement)) {
  throw new Error('No canvas element found');
}

canvas.toBlob((blob) => {
  if (!blob) {
    console.error('The browser did not create an image Blob.');
    return;
  }

  const link = document.createElement('a');
  const objectUrl = URL.createObjectURL(blob);
  link.href = objectUrl;
  link.download = 'canvas.png';
  link.click();

  // Keep the URL available long enough for the download to start.
  setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);
}, 'image/png');

Run this in the page that owns the canvas, after the drawing is complete. If your application redraws asynchronously, trigger the export only after the relevant drawing operation has finished; otherwise the image may reflect an earlier or incomplete state. The example uses a download link. You can instead pass the Blob to an upload operation or create an <img> preview with an object URL.

Object URLs retain a reference to the Blob until revoked. Revoke them when they are no longer needed, but do not revoke one before a user can interact with an image or download that depends on it.

Request another image format

You can request JPEG or WebP by passing a MIME type, for example 'image/jpeg' or 'image/webp'. Browser support may vary. PNG is the safe default; do not assume a requested format was honored without checking the returned Blob’s type.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
canvas.toBlob((blob) => {
  if (!blob) throw new Error('Canvas export failed');
  console.log('Actual MIME type:', blob.type);
}, 'image/webp');

Get a canvas data URL

toDataURL() returns an encoded image string immediately. It defaults to PNG. This is convenient for a quick preview or for passing an image source to code that expects a data URL, but large images can produce long strings.

const canvas = document.querySelector('canvas');
if (!(canvas instanceof HTMLCanvasElement)) {
  throw new Error('No canvas element found');
}

const dataUrl = canvas.toDataURL();
const preview = document.createElement('img');
preview.alt = 'Canvas export';
preview.src = dataUrl;
document.body.append(preview);

To request JPEG, a browser that supports it may accept canvas.toDataURL('image/jpeg', 0.9), where the second argument is a quality hint for lossy formats. The returned format is browser-dependent; the documented safe default is PNG. Avoid using a data URL as a substitute for a Blob when you need to handle a large image efficiently.

Capture a canvas with Playwright

Use a browser screenshot when the deliverable is the rendered page or element, for example in a visual test or when you want to preserve the canvas’s on-page appearance. Playwright can save a page screenshot, request a full-page capture, return screenshot bytes, or screenshot a single locator. Install Playwright and its browser before running a script; the exact installation procedure depends on your project and operating system.

Here is a complete Node.js example for capturing one canvas. It navigates to a page, waits for the canvas locator, and saves the element screenshot:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  try {
    const page = await browser.newPage({ viewport: { width: 1280, height: 900 } });
    await page.goto('https://example.com', { waitUntil: 'load' });

    const canvas = page.locator('canvas').first();
    await canvas.waitFor({ state: 'visible' });
    await canvas.screenshot({ path: 'canvas.png' });
  } finally {
    await browser.close();
  }
})();

Replace https://example.com with the page you control or are authorized to capture. Replace canvas with a more specific CSS selector if the page has several canvases. If the application draws after the element becomes visible, add an application-specific wait condition before taking the screenshot; visibility alone does not prove that drawing is complete.

Capture a page or return screenshot bytes

For the full rendered page, use page.screenshot() with fullPage: true. To receive bytes for processing instead of writing directly to a file, omit path and use the returned buffer:

const pageBytes = await page.screenshot({ fullPage: true });
// Use pageBytes in your test or image-processing pipeline.

For the viewport only, save a regular page screenshot:

await page.screenshot({ path: 'page.png' });

Screenshot option names and availability can vary by Playwright version. Check the Playwright screenshot guide and current Page API for the version used in your project.

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

Fix cross-origin canvas export errors

A canvas becomes tainted when it draws image content from another origin without the required CORS permission. Once it is not origin-clean, browser pixel-reading and export methods such as toBlob() can throw a SecurityError. The same access restriction applies to toDataURL(); switching export methods does not grant permission.

Set CORS before drawing the remote image

For an image that your page is allowed to use, set crossOrigin before assigning its URL, then draw it only after it loads:

const image = new Image();
image.crossOrigin = 'anonymous';
image.onload = () => {
  const canvas = document.querySelector('canvas');
  const context = canvas.getContext('2d');
  context.drawImage(image, 0, 0);
};
image.onerror = () => console.error('Image could not be loaded with CORS permission.');
image.src = 'https://images.example.com/picture.png';

This client-side setting is not sufficient on its own. The remote image server must send a CORS response that permits your page’s origin. If it does not, the browser will not allow the page to read the resulting pixels. Configure the image host or use a source you are authorized to access; do not expect JavaScript to remove the restriction.

If the image was already drawn without the necessary CORS setup, changing the image element afterward does not restore export access to that canvas. Create a clean canvas and redraw only after loading permitted sources correctly.

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

Or skip the browser setup

For a rendered webpage screenshot without installing and managing a browser automation environment, ScreenshotNeo offers a screenshot API and MCP server. It can capture a URL as PNG, JPEG, WebP, or PDF. This captures a rendered page; it is not a replacement for calling toBlob() when your code needs the canvas bitmap itself. Cookie banners, newsletter popups, and chat widgets are removed before the shot; those cleanup steps can each be turned off. Bot checks, blank pages, and failed loads are never billed, and the response identifies the page verdict and billing status in headers. Its MCP server provides screenshot tools for AI agents.

One GET request returns the screenshot. The following cURL example writes a WebP image; replace the URL with the page you need to capture. See the ScreenshotNeo API documentation for parameters and response details.

Best Value
HTML5 Canvas
  • Used Book in Good Condition
curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://example.com 
  -o shot.webp

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots. Sign up for ScreenshotNeo’s free plan to try it without a card.

Troubleshooting canvas captures

  • SecurityError during export: A cross-origin resource may have tainted the canvas. Set CORS on the image before loading and confirm that the remote server grants permission, then redraw to a clean canvas.
  • The callback receives null: Check that a canvas exists and has completed drawing, and request PNG to rule out an unsupported requested format.
  • The saved file is blank or incomplete: Wait for the application’s drawing logic, fonts, data, and any images to finish before calling the export or screenshot method. A visible canvas can still be waiting for its content.
  • The wrong canvas was captured: Use a specific selector and verify that it matches the intended element; locator('canvas').first() selects only the first match.
  • The image is the right content but wrong format: Inspect the Blob’s type. PNG is the default when the requested type is unsupported; do not infer output format from the request alone.
  • The Playwright script cannot launch: Confirm Playwright and its browser binary are installed for the project, and consult the installation guidance for the version in use.

Performance, reliability, and cost considerations

Canvas export runs in the page and avoids capturing unrelated page content. Data URLs can be unwieldy for large images; a Blob is generally a more practical file or upload boundary. Browser screenshots require a browser session and the page to reach the state you intend to capture, so make readiness conditions explicit in automated workflows. Neither method guarantees that a dynamic page has finished rendering unless your code waits for the relevant application state.

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

Screenshot services trade local browser setup for a remote request and service-specific configuration. ScreenshotNeo’s plans are Free: 1,000 shots per month with no card; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; and Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. These are screenshot-service allowances, not a method for exporting a tainted canvas’s protected pixel data.

Which method should you use?

  • Use toBlob() for a canvas image file, upload, or Blob-based processing.
  • Use toDataURL() when an API specifically needs an inline data URL and the image size is manageable.
  • Use Playwright when you need the rendered element or page, or when a visual test should capture what the browser displays.
  • Fix CORS at the resource host and before drawing when you need direct access to cross-origin image pixels.

Frequently Asked Questions

Can I export a canvas that has already been tainted?

Not through the page’s canvas pixel-export methods. Load permitted cross-origin resources with CORS before drawing, then redraw onto a clean canvas.

Does a page screenshot return a canvas as a separate image?

A page screenshot captures a rendered page or selected element. To obtain a standalone canvas bitmap, use a canvas export method such as toBlob().

Can Selenium take an element screenshot?

Selenium documentation describes element screenshot capture, but the exact method depends on the language binding and version. Check the versioned API documentation for the binding you use.

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

Quick Recap

Bestseller No. 1
SaleBestseller No. 3
Bestseller No. 5
HTML5 Canvas
HTML5 Canvas
Used Book in Good Condition
$78.00

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.