我使用javascript和html画布来调整jpeg图像的大小。调整大小后,我使用canvas.toDataURL
作为锚标记中的href属性,以便提供用户可以下载已调整大小的图像的链接。
这可以很好地达到某个图像大小。
似乎不同的浏览器对数据网址的大小有不同的限制,如下所述: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs
在Chrome中,当我超出数据网址大小限制时,点击下载链接时没有任何反应;没有错误或任何事情(据我所知)。
是否有某种方法可以通过编程方式检测数据网址是否过大?也许某些浏览器事件会告诉我点击下载链接是否失败?
理想情况下,我想检测下载是否成功。当数据网址太大时,我想向最终用户显示一个解释,说明如何右键点击图片并选择"另存为...",这似乎总能正常工作。
更新1:
看起来使用canvas.toBlob
是目前最好的解决方法。这是api文档:https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob。
这里有一个jsfiddle,演示了在使用toDataURL
更大的画布时锚点href下载链接失败,但toBlob
似乎有用:
https://jsfiddle.net/upgradingdave/c76q34ac/3/
以下是一些相关的stackoverflow问题: canvas.toDataURL() download size limit
答案 0 :(得分:7)
不,似乎没有任何事件让您知道具有download
属性的锚是否实际上成功下载了资源。
但是,您所面临的限制似乎只涉及这种情况:具有<a>
属性的锚元素download
。
浏览器可以处理更长的dataURI(我认为在大多数浏览器中,限制与字符串长度的限制相同)。例如,它可以将其加载到<img>
元素,更重要的是,在您的情况下,它可以处理dataURI字符串。
这很重要,因为它允许您将此dataURI转换为blob,然后从此blob创建object URL
。 object URL
的URI很小,在download
属性的锚点中不会遇到此长度限制。
因此,您的情况最好的可能是直接使用canvas.toBlob
方法(a polyfill is available on mdn),并将object URL
的URI作为您的href
传递锚
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = function(){
var ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = this.width*10;
ctx.canvas.height = this.height*10;
ctx.drawImage(this,0,0,ctx.canvas.width, ctx.canvas.height);
// convert our canvas to a png blob
// (for type use the second parameter, third is for quality if type is image/jpeg or image/webp)
ctx.canvas.toBlob(function(blob){
myAnchor.href = URL.createObjectURL(blob);
});
// since we are dealing with use files, we absolutely need to revoke the ObjectURL as soon as possible
var revokeURL = function(){
// but we have to wait that the browser actually prepared the file to download
requestAnimationFrame(function(){
// we've waited one frame, it's seems to be enough
URL.revokeObjectURL(this.href);
this.href=null;
});
this.removeEventListener('click', revokeURL);
};
myAnchor.addEventListener('click', revokeURL);
};
img.src = 'http://lorempixel.com/200/200/';
<a id="myAnchor" download="anAwesomeImage.png">download</a>
[ Live Demo ] (因为download
属性被SE-Snippets中的某些UA阻止)
但请注意,即使object URL
的字符串表示形式(URI)很短,它实际上会占用浏览器内存中文件的大小,因此直到您对页面进行硬刷新(清除缓存) ,或关闭创建此对象URL的选项卡。所以你绝对需要致电URL.revokeObjectURL()
来清除这个空间
但是,由于没有事件可以确定下载是否真的成功,因此您会遇到onclick
事件,这将在>> 文件下载之前触发。从我的测试中,等待requestAnimationFrame
的单帧就足够了,但我可能错了。
对于那些使用其他来源而不是画布来获取他们的dataURI的人来说,已经有很多关于将dataURI转换为blob的帖子,你可以查看上面提供的mdn polyfill,他们'也是这样做的。