【发布时间】:2020-03-20 02:14:43
【问题描述】:
我想使用 JavaScript 在客户端调整图像大小。我找到了两种解决方案,一种是使用.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);
}
已编辑:
基于Result of html5 Canvas getImageData or toDataURL - Which takes up more memory?,其表示
"DataURL (BASE64) 是将imageData压缩成JPG或PNG,然后转成字符串,这个字符串比BLOB大37%(信息)。"
字符串是什么意思?它与字节大小相同吗?使用我上面提供的代码,大小差异小于 1Kb(小于 1%)。 .toBlob() 总是优于 .toDataURL() 功能吗?还是有特定条件使用.toDataURL()函数会更好?
【问题讨论】:
-
Stack Overflow 努力让事情尽可能不发表意见,所以没有人(希望)会告诉你哪个“更好”。这两种功能都有各自的用途 - 由您决定,根据您的具体情况,哪一种更合适。
-
@HereticMonkey 我不同意,在这种特殊情况下,有一个明确的“更好”选项。 toDataURL 没有 toBlob 没有的用途。这有点像“我应该使用
还是 css 来使我的元素居中”之类的问题,除了 toDataURL 没有官方的弃用消息(还没有),因为它不幸被广泛使用...... -
@Kaiido 这不像
<center>vs. CSS,因为toDataURL和toBlob都是在 HTML 5 中定义的,而不是在 HTML 中定义的一个在 CSS 中。但要清楚;我们不应该对哪个“更好”进行投票,而应该做出事实陈述,读者可以从中得出自己的结论。您的回答几乎可以做到这一点。考虑到it's still in HTML 5.3, with no reference to potential deprecation or obsolesence,如果引用诸如“规范中的早期错误”之类的断言会更好 -
事实上,甚至有人讨论过取代
toBlob以支持基于 Promise 的 asBlob 或 convertToBlob 可用离屏画布。但是,不,没有计划从规范中删除它,正如我所说,它的使用实在太广泛了,现在没有办法回来,但也没有理由在新的应用程序中使用它。 Ps:不再遵循 w3c 的定义,没有人能理解 html5.x 之类的东西,你应该阅读 whatwg 代替(toDataURL 也会持续)
标签: javascript canvas html5-canvas