Canvas toDataUrl增加了图像的文件大小

时间:2012-03-19 15:38:42

标签: javascript canvas data-url

当使用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时,图像尺寸仍然更大但不是那么多。

3 个答案:

答案 0 :(得分:13)

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

我刚刚进行了一些广泛的测试,结果表明创建的数据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

获取数据URI的方法无关紧要,下面的代码段用于验证文件上传的数据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>

答案 1 :(得分:4)

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

答案 2 :(得分:2)

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

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

base64 encoded image size

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

  • firefox = 3.72kB
  • chrome = 3.24kB

转换为dataURL时的原始图像从32kB变为45kB。

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