Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving a Uint8Array array storing RGBA to a .png file

I am currently trying to save a screenshot of a ThreeJS in a specific area to file.

So far I have only tried to get the image to display into a new tab, I have got it to work with

window.open(renderer.domElement.toDataURL("image/png"));

renderer is a THREE.WebGLRenderer object with preserveDrawingBuffer: true

But that uses the entire scene, so I have switched to:

    var gl = renderer.getContext();
    var pixels = new Uint8Array(width * height * 4);
    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    window.open("data:image/png;base64," + btoa(String.fromCharCode.apply(null, pixels)));

With doing that, nothing is rendered other then a grey outlined square

outlined grey square

like image 834
Phased Avatar asked Sep 06 '25 03:09

Phased


1 Answers

Worked out a solution, after realising that the data is not in the correct format for a png.

    var gl = renderer.getContext();
    var pixels = new Uint8Array(width * height * 4);
    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext("2d");
    var imageData = ctx.createImageData(width, height);

    for(var i = 0; i < imageData.data.length; i+=4) {
        imageData.data[i + 0] = pixels[i + 0];
        imageData.data[i + 1] = pixels[i + 1];
        imageData.data[i + 2] = pixels[i + 2];
        imageData.data[i + 3] = pixels[i + 3];
    }

    ctx.putImageData(imageData,0,0);
    window.open(canvas.toDataURL("image/png"));
    canvas.remove();

it is not the nicest way, but it worked.

like image 187
Phased Avatar answered Sep 07 '25 22:09

Phased