Export Pixi.js Canvas to Base64 Securely

This article explains how to securely capture a screenshot and export the canvas state to a base64 image in Pixi.js. You will learn how to use Pixi’s built-in extraction utilities, configure your renderer to avoid blank screen issues, and handle cross-origin resource sharing (CORS) to prevent browser security errors.

Using the Pixi.js Extract Utility

Pixi.js provides a dedicated extract system to convert your display objects or the entire stage into various formats, including base64 strings.

To export your current stage to a base64 image, use the renderer.extract.base64 method:

// For Pixi.js v7 and v8 (asynchronous)
const base64Image = await app.renderer.extract.base64(app.stage);
console.log(base64Image); // Outputs: "data:image/png;base64,..."

If you are using an older version of Pixi.js (v6 or below), the method is synchronous:

// For Pixi.js v6 and below (synchronous)
const base64Image = app.renderer.plugins.extract.base64(app.stage);

Securing Your Canvas Against Tainted Canvas Errors

The primary security concern when exporting a canvas is the browser’s “Tainted Canvas” security policy. If your Pixi.js application loads textures from an external domain without proper CORS authorization, the browser will block any attempts to export the canvas to a base64 string.

To prevent this error, you must ensure that all external assets are loaded with CORS enabled.

1. Configure the Assets Loader

When loading external images, set the crossOrigin property to anonymous:

// Pixi.js v7/v8 Asset Loading
const texture = await Assets.load({
    src: 'https://external-domain.com/image.png',
    data: {
        crossOrigin: 'anonymous',
    }
});

2. Server-Side CORS Headers

The server hosting your external assets must also return the appropriate CORS headers in its HTTP response:

Access-Control-Allow-Origin: *

Preserving the Drawing Buffer

By default, WebGL clears the drawing buffer after rendering each frame to optimize performance. If you attempt to capture the canvas outside of Pixi’s internal render loop, you may end up with a blank or black image.

To securely capture the canvas at any time, you can enable preserveDrawingBuffer when initializing your Pixi application:

const app = new Application();
await app.init({
    width: 800,
    height: 600,
    preserveDrawingBuffer: true // Guarantees the canvas holds its pixels for extraction
});

Note: While enabling preserveDrawingBuffer makes capturing screenshots highly reliable, it can carry a minor performance cost on some mobile devices. If performance is critical, perform your extraction immediately after a manual render call instead:

app.renderer.render(app.stage);
const base64Image = await app.renderer.extract.base64(app.stage);