简体   繁体   中英

Given a canvas object, how can I get a scaled down “version” of it as an image/Base64-encoded byte array?

I am using html2canvas to take "screenshots" of the current browser window. I would like to save the screenshot as Base64 encoded data which can later be used to create an html img. For example, I might want to save the String that canvas.toDataURL() returns in the browser's local storage, and retrieve it later.

The following code works fine:

html2canvas(document.body, {
    onrendered: function(canvas) {
        localStorage.setItem('screenshot', JSON.stringify(canvas.toDataURL()));
    }
});

I can later retrieve it and create an image from it, for example using Angular:

<img data-ng-src="{{imgData}}"/>

What I want to do though, is have a scaled down version of the screenshot. I can simply scale the resulting image using CSS, but I want to save storage space. In other words, I want the String encoding to represent an image that is, for example, 200 pixels wide instead of (say) 1000 pixels wide. I do not care about the quality of the image.

This is the closest I've come:

saveScreenshot = function(name, scaleFactor) {
    html2canvas(document.body, {
        onrendered: function(canvas) {
            var ctx = canvas.getContext('2d');
            var img = new Image();
            img.onload = function() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.scale(scaleFactor, scaleFactor);
                ctx.drawImage(img, 0, 0);
                //canvas.width *= scaleFactor;
                //canvas.height *= scaleFactor;
                localStorage.setItem('screenshot', JSON.stringify(canvas.toDataURL()));
            }
            img.src = canvas.toDataURL();
        }
    });
}

This almost works - the "picture" is scaled correctly, but the resulting image is still the same size as the original, with the rest of the space apparently filled in with transparent pixels.

If I uncomment the 2 lines above which set the canvas' height and width, then the image is the right size, but it's all blank.

I feel like I'm close - what am I missing?

.toDataURL will always capture the entire canvas, so to get a smaller image you must create a second smaller canvas:

var scaledCanvas=document.createElement('canvas');
var scaledContext=scaledCanvas.getContext('2d');
scaledCanvas.width=canvas.width*scaleFactor;
scaledCanvas.height=canvas.height*scaleFactor;

Then scale the second canvas and draw the main canvas onto the second canvas

scaledContext.scale(scaleFactor,scaleFactor);
scaledContext.drawImage(canvas,0,0);

And finally export that second canvas as a dataURL.

var dataURL = scaledCanvas.toDataURL();

Warning: untested code above...but it should put you on the right track!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM