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

Javascript Canvas toDataUrl增加了图像的文件大小,javascript,canvas,data-url,Javascript,Canvas,Data Url,使用toDataUrl()设置图像标记的源时,我发现保存的图像比原始图像大得多 在下面的示例中,我没有为toDataUrl函数指定第二个参数,因此使用默认质量。这将导致图像比原始图像大得多。当为全质量指定1时,生成的图像甚至更大 有人知道为什么会发生这种情况,或者我怎样才能阻止它吗 // create image var image = document.createElement('img'); // set src u

使用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 + '" />');

            }
//创建图像
var image=document.createElement('img');
//使用远程映像位置设置src
image.src='test.jpg';
//等待,直到它已加载
image.onload=函数(){
//设置变量
var fWidth=image.width;
var fHight=图像高度;
//创建画布
var canvas=document.createElement('canvas');
canvas.id='canvas';
canvas.width=fWidth;
canvas.height=fHeight;
var context=canvas.getContext('2d');
//在画布上绘制图像
drawImage(图像,0,0,fWidth,fHeight,0,0,fWidth,fHeight);
//获取数据url
dataUrl=canvas.toDataURL('image/jpeg');
//保存时,此图像比加载的图像大得多
文件。写(“”);
}
谢谢:D

这里是一个例子,不幸的是,这个图像不能跨域,所以我只能拉一个JSFIDLE图像

图像为7.4kb,如果保存正在输出的图像,您将看到它是10kb。通过更详细的图像,差异更为明显。如果将toDataUrl质量设置为1,则图像大小为17kb


我也在使用FireFox 10,当使用Chrome浏览器时,图像大小仍然较大,但没有这么大。

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

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

我刚刚执行了一些广泛的测试,结果表明创建的数据URL取决于浏览器(而不是操作系统)

获取数据URI的方法无关紧要,以下代码段用于验证文件上载的数据URI是否也不同:

测试用例:

document.getElementById('file')。onchange=function(){
var filereader=newfilereader();
filereader.onload=函数(事件){
var img=新图像();
img.onload=函数(){
var c=document.createElement('canvas');//创建画布
c、 宽度=img.width;
c、 高度=img.height;c.getContext('2d').drawImage(img,0,0,img.width,img.height);
var toAppend=新图像;
toAppend.title='通过上传导入,在画布中绘制';
toAppend.src=c.toDataURL('image/png');
document.body.appendChild(toAppend);
}
img.src=event.target.result;//从上传设置src,原始字节序列
img.title='通过文件上传导入';
文件.正文.附件(img);
};
filereader.readAsDataURL(this.files[0]);
}

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

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

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

  • firefox=3.72kB
  • chrome=3.24kB
转换为dataURL时,我的原始图像从32kB变为45kB


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

dataURL存储在
base64
中,而不是二进制(大小增加1/3)。此外,浏览器中使用的存储算法可能不像最初使用的那样优化。这仅适用于远程存储的图像,使用文件输入加载的图像大小正确。它们是否相同?真实站点上的远程图像可能会得到更好的优化。我知道,作为示例,我使用的远程图像是59kb。从上面生成的图像标记重新保存后,图像被称为134kb。将此59kb图像保存到我的HD,然后将结果上载到59kb图像。由于某些原因,当图像是远程的时,它会使生成的图像变得更大。这是一个很好的问题,因为有很多文章介绍了如何在将图像上载到服务器之前在客户端上“缩小”图像。然而,我读过的文章中没有一篇提到这个数据膨胀的问题。只有在浪费了几个小时之后,人们才意识到画布并不是一个很好的图像缩放解决方案+1非常有用的答案。感谢您确认编码行为一致且特定于浏览器。需要注意的是,至少Chrome v56生成的非渐进式JPEG比渐进式JPEG稍大(特别是当质量为0..10和90..100时)
我想我现在的计划是将dataURL转换回一个二进制字节数组
,该数组还将提供比原始图像字节数据更大的字节数据。。。
 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
<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>