.toDataURL()
FileReader
对象也有类似的方法,比如.readAsDataURL()
,然而它只接受file
或blob
类型,而这两种类型一般只能通过<input[type=file]>
元素的files
属性获取,或者用Blob()
构造函数手工创建一个新的对象。尴尬的是我们当前只有图片路径,受制于浏览器的安全策略,<input[type=file]>
的files
属性是只读的,而Blob()
构造函数只接受文件内容,两种方式都无法通过图片路径直接获取。上文中假设的应用场景迫使我们必先考虑如何通过路径获取到图片内容。<img>
是可以的,并且可以被绘制到<canvas>
中,而<canvas>
正巧拥有.toDataURL()
方法。
万事具备,我们只需要把<img>
获取到的图片放到<canvas>
里再通过.toDataURL()
方法转化下,就可以得到以 base64 编码的 dataURL。来看这个方法的语法:
canvas.toDataURL([type, encoderOptions]);
canvas 是 DOM 元素<canvas>
对象;参数type
指定图片类型,如果指定的类型不被支持则以默认值image/png
替代;encoderOptions
可以为image/jpeg
或image/webp
类型的图片设置图片质量,取值0-1
,超出则以默认值0.92
替代。
需要注意的是,图片加载是异步的,在转换成 dataURL 前必须先确保图片成功加载到,否则让 canvas 即刻执行绘制可能失败,从而导致转换 dataURL 失败。于是.toDataURL()
方法应该写在<img>
的onload
事件中,以确保 canvas 的绘制工作在图片下载完成后开始。好在.drawImage()
方法是同步的,只有在 canvas 绘制完成后才会执行后续操作,比如.toDataURL()
。