给定一个 canvas 对象,我怎样才能将它的 "version" 缩小为 image/Base64-encoded 字节数组?

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

我正在使用 html2canvas 获取当前浏览器 window 的 "screenshots"。我想将屏幕截图保存为 Base64 编码数据,稍后可用于创建 html img。例如,我可能想将 canvas.toDataURL() returns 的字符串保存在浏览器的本地存储中,稍后再检索它。

以下代码工作正常:

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

我可以稍后检索它并从中创建图像,例如使用 Angular:

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

不过我想做的是截屏的缩小版。我可以简单地使用 CSS 缩放生成的图像,但我想节省存储空间 space。换句话说,我希望 String 编码表示一个图像,例如,200 像素宽而不是(比方说)1000 像素宽。我不关心图像的质量。

这是我最近的一次:

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();
        }
    });
}

几乎 有效 - "picture" 已正确缩放,但生成的图像仍与原始图像大小相同,其余 space 显然填充了透明像素。

如果我取消注释上面设置画布高度和宽度的 2 行,则图像大小正确,但全是空白。

我觉得我很接近 - 我错过了什么?

.toDataURL 将始终捕获整个 canvas,因此要获得较小的图像,您必须创建第二个较小的图像 canvas:

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

然后缩放第二个 canvas 并将主要 canvas 绘制到第二个 canvas

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

最后将第二个 canvas 导出为数据 URL。

var dataURL = scaledCanvas.toDataURL();

警告:上面的代码未经测试...但它应该会让您走上正轨!