Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to get canvas image data via toDataURL #246

Open
j9a12c20k opened this issue Feb 25, 2023 · 1 comment
Open

Trying to get canvas image data via toDataURL #246

j9a12c20k opened this issue Feb 25, 2023 · 1 comment

Comments

@j9a12c20k
Copy link

j9a12c20k commented Feb 25, 2023

Hello,

I am trying to get canvas image data in JSDOM. I wrapped headless-gl functions to jsdom to add web gl functionality, however headless-gl does not seem to have canvas.toDataURL() option. Is there a way to add this functionality?

Thanks

import gl from 'gl';

import jsdom from "jsdom";

const JSDOM = jsdom.JSDOM;
const dom = new JSDOM(`<html><head></head><body></body></html>`, {
  url: "https://example.com",
  beforeParse(window) {
    window = beforeParse(window);
  }
});

dom.window.eval(`

const webgl = window.document.createElement('canvas');

// window.WebGLRenderingContext.prototype.getParameter.name
// window.WebGLRenderingContext.prototype.getParameter
const g = webgl.getContext("webgl")
console.log(g.canvas.toDataURL());
//^ need to get the canvas to get the image data (returns undefined)
`)


function beforeParse() {
  const orig_getContext = window.HTMLCanvasElement.prototype.getContext
  window.HTMLCanvasElement.prototype.getContext = function () {
    if (arguments[0] === 'webgl') {
        const ctx = gl.create(1, 1, arguments[1])
        ctx.resize = ctx.getExtension('STACKGL_resize_drawingbuffer').resize
        return ctx
    } else {
        return orig_getContext.apply(this, arguments)
    }
}
}
@dhritzkiv
Copy link
Member

headless-gl itself does not provide a canvas element or image output functionality.

However, if you have a way to add toDataURL a method to HTMLCanvasElement, you can implement it yourself with something like:

// `width` and `height` are the dimensions of your canvas
const pixels = new Uint8Array(4 * width * height);

// `gl` is the gl context of this context.
// we pass the `pixels` array as the last argument 
// RGBA format is used 
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

// get the data buffer from the pixels array
const buffer = Buffer.from(pixels.buffer);

// pass this bitmap data to a method that can encode it as a PNG / JPEG. I use `sharp`, but there are others, such as `jpeg-js`, `pngjs3`, etc.
// ...

When creating your gl context, make sure to pass preserveDrawingBuffer: true to the constructor options. You may also want, antialias: true and alpha: true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants