WebGL single frame “screenshot” of webGL

2019-02-15 19:42发布

问题:

tried searching for something like this, but I've had no luck. I'm trying to open a new tab with a screenshot of the current state of my webgl image. Basically, it's a 3d model, with the ability to change which objects are displayed, the color of those objects, and the background color. Currently, I am using the following:

var screenShot = window.open(renderer.domElement.toDataURL("image/png"), 'DNA_Screen');

This line succeeds in opening a new tab with a current image of my model, but does not display the current background color. It also does not properly display the tab name. Instead, the tab name is always "PNG 1024x768".

Is there a way to change my window.open such that the background color is shown? The proper tab name would be great as well, but the background color is my biggest concern.

回答1:

If you open the window with no URL you can access it's entire DOM directly from the JavaScript that opened the window.

var w = window.open('', '');

You can then set or add anything you want

w.document.title = "DNA_screen";
w.document.body.style.backgroundColor = "red";

And add the screenshot

var img = new Image();
img.src = someCanvas.toDataURL();
w.document.body.appendChild(img);


回答2:

Well it is much longer than your one liner but you can change the background color of the rectangle of the context.

printCanvas (renderer.domElement.toDataURL ("image/png"), width, height,
    function (url) { window.open (url, '_blank'); });

// from THREEx.screenshot.js
function printCanvas (srcUrl, dstW, dstH, callback)
{
    // to compute the width/height while keeping aspect
    var cpuScaleAspect = function (maxW, maxH, curW, curH)
    {
        var ratio = curH / curW;
        if (curW >= maxW && ratio <= 1)
        {
            curW = maxW;
            curH = maxW * ratio;
        }
        else if (curH >= maxH)
        {
            curH = maxH;
            curW = maxH / ratio;
        }

        return { width: curW, height: curH };
    }

    // callback once the image is loaded
    var onLoad = function ()
    {
        // init the canvas
        var canvas = document.createElement ('canvas');
        canvas.width = dstW;
        canvas.height = dstH;

        var context    = canvas.getContext ('2d');
        context.fillStyle = "black";
        context.fillRect (0, 0, canvas.width, canvas.height);

        // scale the image while preserving the aspect
        var scaled    = cpuScaleAspect (canvas.width, canvas.height, image.width, image.height);

        // actually draw the image on canvas
        var offsetX    = (canvas.width  - scaled.width ) / 2;
        var offsetY    = (canvas.height - scaled.height) / 2;
        context.drawImage (image, offsetX, offsetY, scaled.width, scaled.height);

        // notify the url to the caller
        callback && callback (canvas.toDataURL ("image/png"));    // dump the canvas to an URL        
    }

    // Create new Image object
    var image = new Image();
    image.onload = onLoad;
    image.src = srcUrl;
}