Javascript 我应该使用哪个函数。toDataURL()或.toBlob()?
我想使用JavaScript在客户端调整图像大小。我找到了两种解决方案,一种是使用Javascript 我应该使用哪个函数。toDataURL()或.toBlob()?,javascript,canvas,html5-canvas,Javascript,Canvas,Html5 Canvas,我想使用JavaScript在客户端调整图像大小。我找到了两种解决方案,一种是使用.toDataURL()函数,另一种是使用.toBlob()函数。两种解决方案都有效。我只是想知道这两个函数有什么区别?哪一个更好?或者何时应该使用.toDataURL()函数或.toBlob()函数 这是我用来输出这两个函数的代码,我得到的图像大小(字节)和图像颜色(我不确定这一个)略有不同。代码有问题吗 <html> <head> <title>Php
.toDataURL()
函数,另一种是使用.toBlob()
函数。两种解决方案都有效。我只是想知道这两个函数有什么区别?哪一个更好?或者何时应该使用.toDataURL()
函数或.toBlob()
函数
这是我用来输出这两个函数的代码,我得到的图像大小(字节)和图像颜色(我不确定这一个)略有不同。代码有问题吗
<html>
<head>
<title>Php code compress the image</title>
</head>
<body>
<input id="file" type="file" onchange="fileInfo();"><br>
<div>
<h3>Original Image</h3>
<img id="source_image"/>
<button onclick="resizeImage()">Resize Image</button>
<button onclick="compressImage()">Compress Image</button>
<h1 id="source_image_size"></h1>
</div>
<div>
<h3>Resized Image</h3>
<h1> image from dataURL function </h1>
<img id="result_resize_image_dataURL"/>
<h1> image from toBlob function </h1>
<img id="result_resize_image_toBlob"/>
</div>
<div>
<fieldset>
<legend>Console output</legend>
<div id='console_out'></div>
</fieldset>
</div>
<script>
//Console logging (html)
if (!window.console)
console = {};
var console_out = document.getElementById('console_out');
var output_format = "jpg";
console.log = function(message) {
console_out.innerHTML += message + '<br />';
console_out.scrollTop = console_out.scrollHeight;
}
var encodeButton = document.getElementById('jpeg_encode_button');
var encodeQuality = document.getElementById('jpeg_encode_quality');
function fileInfo(){
var preview = document.getElementById('source_image');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function(e) {
preview.src = e.target.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
function resizeImage() {
var loadedData = document.getElementById('source_image');
var result_image = document.getElementById('result_resize_image_dataURL');
var cvs = document.createElement('canvas'),ctx;
cvs.width = Math.round(loadedData.width/4);
cvs.height = Math.round(loadedData.height/4);
var ctx = cvs.getContext("2d").drawImage(loadedData, 0, 0, cvs.width, cvs.height);
cvs.toBlob(function(blob) {
var newImg = document.getElementById('result_resize_image_toBlob'),
url = URL.createObjectURL(blob);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
console.log(blob.size/1024);
}, 'image/jpeg', 0.92);
var newImageData = cvs.toDataURL('image/jpeg', 0.92);
var result_image_obj = new Image();
result_image_obj.src = newImageData;
result_image.src = result_image_obj.src;
var head = 'data:image/png;base64,';
var imgFileSize = ((newImageData.length - head.length)*3/4)/1024;
console.log(imgFileSize);
}
Php代码压缩图像
原始图像
编辑:
根据,它说,
DataURL(BASE64)是将imageData压缩为JPG或PNG,然后转换为字符串,此字符串比BLOB大37%(信息)
字符串是什么意思?它与字节大小相同吗?使用上面提供的代码,大小差异小于1Kb(小于1%)。.toBlob()
是否总是优于.toDataURL()
函数?或者有一个特定的条件,使用.toDataURL()
函数更好?一定要使用toBlob()
toDataURL
实际上只是规范中的一个早期错误,如果几个月后定义它,它肯定不会再出现在这里,因为我们可以使用toBlob
做同样的事情,但会更好
toDataURL()
是同步的,在执行不同的操作时会阻止用户界面
- 将位图从GPU移动到CPU
- 转换为图像格式
- 转换为base64字符串
另一方面,toBlob()
将仅同步执行第一个项目符号,但将以非阻塞方式转换为图像格式。而且,它不会执行第三个项目符号。
因此,在原始操作中,这意味着toBlob()
以更好的方式做得更少
toDataURL
结果占用的内存比toBlob
多。
toDataURL
返回的数据URL是一个,其中包含在base64中压缩的完整二进制数据。
正如您在问题中引用的那样,base64编码本身意味着二进制数据现在将增加约37%。但在这里,它不仅编码为base64,而且使用UTF-16编码存储,这意味着每个ascii字符将占用原始ascii文本所需内存的两倍,我们跳转到一个比原始二进制数据大174%的文件…
而且还没有结束。。。每次在某处使用此字符串时,例如作为DOM元素*的src
,或通过网络请求发送时,此字符串可以再次在内存中重新分配。
*尽管现代浏览器似乎有处理这种情况的机制
您(几乎)不需要数据url。
使用数据url所能做的一切,都可以使用Blob和Blob URI做得更好
要显示或本地链接到二进制数据(例如供用户下载),请使用Blob URI,使用URL.createObjectURL()
方法。
它只是指向Blob本身指向的内存中二进制数据的指针。这意味着您可以根据需要多次复制blob URI,它将始终是一个约100个字符的UTF-16字符串,并且二进制数据不会移动
如果您希望将二进制数据发送到服务器,或通过
如果希望将其保存在本地,请使用,它可以保存二进制文件。在LocalStorage中存储二进制文件是一个非常糟糕的主意,因为每次加载页面时都必须加载存储对象
您可能需要数据URL的唯一情况是,如果您希望创建需要嵌入二进制数据的独立文档,在当前文档死后可以访问。但即使如此,要从画布创建图像的数据url版本,请使用一个将canvas.toBlob()
返回的Blob传递到的url。这将有助于实现完全的异步转换,避免您的用户界面因为没有好的理由而被阻塞。堆栈溢出的可能副本会尽力让事情尽可能没有意见,所以没有人(希望)会告诉您哪一个“更好”。这两种功能都有各自的用途——根据您的具体情况,由您决定哪一种更合适。@我不同意,在这种情况下,有一个明确的“更好”选项。toDataURL没有toBlob没有的用途。这有点像“我应该使用或css来居中我的元素”之类的问题,除了toDataURL没有官方的反对消息,因为它不幸被广泛使用…@kaido它不像
与css,因为toDataURL
和toBlob
都是在HTML 5中定义的,不是HTML中的一个,而是CSS中的一个。但要说清楚;我们不应该投票决定哪一个更好,而应该陈述事实,读者可以从中得出自己的结论。你的答案几乎就是这样。如果引用“规范中的早期错误”之类的断言会更好,考虑到事实是,已经有人讨论过甚至取代toBlob
,以支持基于承诺的asBlob或convertToBlob,因为后者在CreencaNVA上可用。但是,不,没有计划从规范中删除它,正如我所说的,它的使用真的太广泛了,现在没有办法回来,但是也没有理由在新的应用中使用它。附言:w3c的定义不再被遵循了,没有其他人理解html5.x这样的东西。你应该阅读whatwg(也将持续下去)。这是一个极好的答案。非常感谢您的详细解释。在什么情况下,dataURL是合理的?相关问题:我们使用base64存储操纵图形的历史状态,但是