【问题标题】:Canvas toDataUrl increases file size of imageCanvas toDataUrl 增加图像的文件大小
【发布时间】:2012-04-04 02:44:53
【问题描述】:

当使用 toDataUrl() 设置图像标签的来源时,我发现保存时的图像比原始图像大很多。

在下面的示例中,我没有为 toDataUrl 函数指定第二个参数,因此使用了默认质量。这导致图像比原始图像尺寸大得多。当指定 1 表示完整质量时,生成的图像会更大。

有人知道为什么会发生这种情况或我该如何阻止它吗?

            // create image
            var image = document.createElement('img');

            // set src using remote image location
            image.src = 'test.jpg';

            // wait til it has loaded
            image.onload = function (){

            // set up variables
            var fWidth = image.width;
            var fHeight = image.height;

            // create canvas
            var canvas = document.createElement('canvas');
            canvas.id = 'canvas';
            canvas.width = fWidth;
            canvas.height = fHeight;
            var context = canvas.getContext('2d');

            // draw image to canvas
            context.drawImage(image, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight);

            // get data url 
            dataUrl =  canvas.toDataURL('image/jpeg');

            // this image when saved is much larger than the image loaded in
            document.write('<img src="' + dataUrl + '" />');

            }

谢谢你:D

这是一个例子,不幸的是图像不能跨域,所以我只需要拉一个 jsfiddle 图像。

http://jsfiddle.net/ptSUd/

图像是 7.4kb,如果你保存正在输出的图像,你会看到它是 10kb。使用更详细的图像时,差异会更加明显。如果将 toDataUrl 质量设置为 1,则图像为 17kb。

我也在为此使用 FireFox 10,当使用 Chrome 时,图像尺寸仍然更大,但没有那么大。

【问题讨论】:

  • dataUrl 存储在 base64 中,而不是二进制(大小增加 1/3)。此外,浏览器中使用的存储算法可能不如最初使用的那么优化。
  • 这仅适用于远程存储的图像,使用文件输入加载的图像大小正确。
  • 它们是一样的吗?真实站点上的远程图像可能会得到更好的优化。
  • 我知道我作为示例使用的远程图像是 59kb。从上面生成的图像标签重新保存后,图像被称为 134kb。将此 59kb 图像保存到我的 HD,然后将结果上传到 59kb 图像。由于某种原因,当图像是远程的时,它会使生成的图像变得更大。
  • 非常好的问题,因为有很多文章展示了如何在客户端上“缩小”图像,然后再将其上传到服务器。然而,我读过的文章都没有提到这个数据膨胀问题。只有在浪费了几个小时之后,人们才意识到画布并不是一个很好的图像调整解决方案。 +1

标签: javascript canvas data-url


【解决方案1】:

toDataURL()方法返回的字符串不代表原始数据。

我刚刚进行了一些广泛的测试,结果表明创建的 data-URL 取决于浏览器(不取决于操作系统)。

 Environment             -    md5 sum                       - file size
    Original file        - c9eaf8f2aeb1b383ff2f1c68c0ae1085 - 4776 bytes
WinXP Chrome 17.0.963.79 - 94913afdaba3421da6ddad642132354a - 7702 bytes
Linux Chrome 17.0.963.79 - 94913afdaba3421da6ddad642132354a - 7702 bytes
Linux Firefox 10.0.2     - 4f184006e00a44f6f2dae7ba3982895e - 3909 bytes

获取data-URI的方法无关紧要,下面的sn-p用来验证文件上传的data-URI也不同:

测试用例:http://jsfiddle.net/Fkykx/

<input type="file" id="file"><script>
document.getElementById('file').onchange=function() {
    var filereader = new FileReader();
    filereader.onload = function(event) {
        var img = new Image();
        img.onload = function() {
            var c = document.createElement('canvas'); // Create canvas
            c.width = img.width;
            c.height = img.height;  c.getContext('2d').drawImage(img,0,0,img.width,img.height);
            var toAppend = new Image;
            toAppend.title = 'Imported via upload, drawn in a canvas';
            toAppend.src = c.toDataURL('image/png');
            document.body.appendChild(toAppend);
        }
        img.src = event.target.result; // Set src from upload, original byte sequence
        img.title = 'Imported via file upload';
        document.body.appendChild(img);
    };
    filereader.readAsDataURL(this.files[0]);
}
</script>

【讨论】:

  • 非常有帮助的答案。感谢您确认编码行为是一致的并且是特定于浏览器的。
  • 需要注意的一点是,至少 Chrome v56 会生成比渐进式稍大的非渐进式 jpeg(尤其是当质量为 0..10 和 90..100 时)
【解决方案2】:

图像的大小主要取决于浏览器内置编码器的质量。它与原始图像的大小关系不大。一旦你在canvas 上绘制任何东西,你所拥有的只是像素,你就不再拥有原始图像。 toDataURL 不会神奇地重建绘制在 canvas 上的图像。如果您想要与原始图像大小相同的文件:使用原始图像。

【讨论】:

    【解决方案3】:

    看起来 kirilloid 和 Rob 搞定了。我也有这个问题,它似乎是一个组合:

    • dataURL 使用 base64 编码,使其大约大 1.37 X
    • 每个浏览器处理 toDataURL 函数的方式不同

    base64 encoded image size

    我在 win8.1 firefox 和 chrome 中测试了我的缩略图生成器,得到了 dataURL 字符串大小:

    • 火狐=3.72kB
    • 铬 = 3.24kB

    我的原始图像在转换为 dataURL 后从 32kB 变为 45kB。

    我认为 base64 部分是更大的因素,所以我想我现在的计划是将 dataURL 转换回二进制字节数组,然后再将其存储在服务器上(可能在客户端,因为我的服务器很懒惰)。

    【讨论】:

    • I guess my plan now is to convert the dataURL back to a binary byte array 这也会为您提供比原始图像字节数据更大的字节数据...
    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多