- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 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) is imageData compressed to JPG or PNG, then converted to string, and this string is larger by 37% (info) than BLOB."
这个字符串是什么意思?它与以字节为单位的大小相同吗?使用我上面提供的代码,大小差异小于 1Kb(小于 1%)。 .toBlob()
总是比 .toDataURL()
函数更好吗?或者在特定条件下最好使用 .toDataURL()
函数?
最佳答案
一定要选择toBlob()
.
toDataURL
实际上只是规范中的一个早期错误,如果几个月后定义它,它肯定不会再出现了,因为我们可以使用 toBlob
做同样的事情,但效果更好。 .
toDataURL()
是同步的,并且在执行不同操作时会阻塞您的 UI toBlob()
另一方面,只会同步执行第一个项目符号,但会以非阻塞方式转换为图像格式。而且,它根本不会执行第三个项目。
所以在原始操作中,这意味着 toBlob()
以更好的方式做更少的事情。
toDataURL
结果占用的内存比 toBlob
更多的。toDataURL
返回的数据 URL是 USVString ,其中包含以 base64 压缩的完整二进制数据。
正如您问题中的引述所述,base64 编码本身意味着二进制数据现在将增大约 37%。但这里它不仅编码为base64,还使用UTF-16编码存储,这意味着每个ascii字符将占用原始ascii文本所需内存的两倍,并且我们跳转到比原始二进制数据大174%的文件。 ..
一切还没有结束...每次你在某个地方使用这个字符串时,例如 src
DOM 元素*,或者通过网络请求发送它时,该字符串可以再次在内存中重新分配。
*尽管现代浏览器似乎有处理这种情况的机制
使用 data-url 可以做的所有事情,使用 Blob 和 Blob-URI 都可以做得更好。
要显示或本地链接到二进制数据(例如,供用户下载),请使用 Blob-URI,使用 URL.createObjectURL()
方法。
它只是一个指向 Blob 本身所指向的内存中保存的二进制数据的指针。这意味着您可以根据需要多次复制 blob-URI,它始终是一个约 100 个字符的 UTF-16 字符串,并且二进制数据不会移动。
如果您希望将二进制数据发送到服务器,send it as binary directly ,或通过 multipart/formdata request .
如果您希望将其保存在本地,请使用IndexedDB ,它能够保存二进制文件。在 LocalStorage 中存储二进制文件是一个非常糟糕的主意,因为必须在每次页面加载时加载 Storage 对象。
您可能需要 data-urls 的唯一情况是,如果您希望创建需要嵌入二进制数据的独立文档,以便在当前文档失效后可以访问。但即便如此,要从 Canvas 创建图像的 data-url 版本,请使用 FileReader您将 canvas.toBlob()
返回的 Blob 传递给它。这将实现完全的异步转换,避免您的 UI 无缘无故被阻止。
关于javascript - 我应该使用哪个功能? .toDataURL() 还是 .toBlob()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59020799/
我已将 javascript 方法 toDataURL 返回的字符串保存在数据库中。示例如下: http://pastebin.com/0Qu8rngD 我需要在 django 响应中返回图像。像这样
我正在尝试创建 Canvas 绘图,但是当我使用 toDataUrl 时,它返回空 Canvas 文件。 这可能是因为 toDataUrl 在我的图像加载之前已触发,所以我该如何更改它,以便我尝试加载
我正在尝试生成 Canvas 的网址。以下是我遵循的步骤: var can = document.getElementsByTagName("canvas"); var src = can.toDat
assets.forEach(function(v) { var canvas = document.createElement('canvas'); canvas.id =
我有一份包含图表和表格的报告。 我正在使用 html2canvas与 jsPDF将此报告导出为 PDF 文件。 但是这个过程耗时很长,超过11000ms。 我尝试更改格式和质量,但没有任何效果。 请看
当我在浏览器中上传某个文件时,该文件类型为 jpeg,文件大小为 2MB,但是当我使用 canvas.toDataURL() 将文件编码为 Base64 时,大小为生成的文件约为 9MB。 为什么ba
toDataURL() 正在保存在 Canvas 上绘制的黑色覆盖/背景;但不是通过链接在同一 Canvas 上绘制图像。如果我只绘制一个图像并尝试将其保存为图像,则保存的是透明图像。 我研究了很多东
我正在尝试创建一些将文本保存到图像的工具,现在我已经构建了一些可以预览的工具。但我在下载时遇到了一个问题,它不断下载损坏的图像...... 我尝试了很多方法,但似乎没有任何效果,到目前为止我的下载代码
我有两套用于测试 html5 canvas 的代码 第 1 组 - 完美工作 var c = document.getElementById("myCanvas"); var ctx = c.ge
我有问题 .toDataURL()用于大 Canvas 。我想转告 base64并在 php 文件上解码,但如果我有一个大 Canvas ,strDataURI变量为空。 我的代码: var strD
我正在尝试在 python 中做与在 JavaScript 中完全相同的事情。在 JavaScript 中,我可以轻松地在 Canvas 上绘图,然后使用 toDataUrl(imageFormat,
你好, 我想裁剪我的 canvas.toDataURL()在将它发送到服务器之前,但我没有找到如何:( 这是我的代码: TakePhoto: function() { var myCa
我正在尝试实现this signature pad plugin进入我的 ColdFusion 应用程序。但是,我正在努力弄清楚如何使用 todataURL() 函数将 Canvas 绘图设置为 Co
我尝试过实现 signature_pad ,但说实话我不太明白。 如何返回图像值并将其发布到我的服务器? 编辑: 我尝试过解码: JavaScript“app.js”: saveButton.addE
转到 this website 。 打开控制台并写入: ` var canvas = $("#mandelbox-canvas")[0]; var imgData = canvas.toDataURL
在android PhoneGap应用程序中,我使用html创建 Canvas 并在该 Canvas 中显示图像。然后使用canvas.toDataURL(image/jpg)尝试将图像转换为base
每当我尝试运行此程序时,我都会在 chrome 中收到类型错误:代码更新 // Get the drawing canvas canvas = $('#drawing'); context = can
我正在使用canvas 将图像转换为base64。我需要做的是转换这些图像,然后向用户显示结果(原始图像和 Base64 版本)。对于小图像,一切都按预期工作,但是当我尝试转换大图像(> 3MB)并且
我正在使用 Flot 版本 0.8.3 来显示多种类型的图表。我为用户提供了使用 .toDataURL('img/png') 从 Canvas 导出图表的选项。 导出的图像未显示刻度轴标签。我最终发现
我正在尝试将 HTML5 Canvas 的内容转换为 png 图像。 问题是 Canvas 包含未在本地托管的图像,因此出现安全错误。 我没有在本地托管图像的选项,有没有其他方法可以捕获 Canvas
我是一名优秀的程序员,十分优秀!