利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
将图片转为base64的好处
将图片转换为Base64编码,可以让你很方便地在没有上传文件的条件下将图片插入其它的网页、编辑器中。这对于一些小的图片是极为方便的,因为你不需要再去寻找一个保存图片的地方。
将图片转换成base64编码的,在web网上一般用于小图片上,不仅可以减少图片的请求数量(集合到js、css代码中),还可以防止因为一些相对路径等问题导致图片404错误。
引言
假设一个应用场景:由于某些特殊原因从服务端请求到图片路径,要求通过该路径获取对应图片的base64dataURL。在这个场景中,我们首先推断该图片路径是可访问的,同时还需要一种将图片转换到dataURL的方法。
我们如何实现它呢?
dataURL
先大致回顾下正统的dataURL的语法,这有助于我们检验转换后的内容是否正确。一个完整的dataURI应该是这样的:
data:[][;base64],
其中mediatype声明了文件类型,遵循MIME规则,如“image/png”、“text/plain”;之后是编码类型,这里我们只涉及base64;紧接着就是文件编码后的内容了。我们常常在HTML里看到img标签的src会这样写:
src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7"
这个img引用的就是以base64编码的dataURL了,只要浏览器支持,就可以被解码成gif图片并渲染出来。
.toDataURL()
FileReader对象也有类似的方法,比如.readAsDataURL(),然而它只接受file或blob类型,而这两种类型一般只能通过元素的files属性获取,或者用Blob()构造函数手工创建一个新的对象。尴尬的是我们当前只有图片路径,受制于浏览器的安全策略,的files属性是只读的,而Blob()构造函数只接受文件内容,两种方式都无法通过图片路径直接获取。上文中假设的应用场景迫使我们必先考虑如何通过路径获取到图片内容。是可以的,并且可以被绘制到
万事具备,我们只需要把获取到的图片放到
canvas.toDataURL([type,encoderOptions]);
canvas是DOM元素
需要注意的是:在转换成dataURL前必须先确保图片成功加载到,于是.toDataURL()方法应该写在的onload异步事件中。现在就来实现一个功能函数:
functiongetBase64(url){ //通过构造函数来创建的img实例,在赋予src值后就会立刻下载图片,相比createElement()创建省去了append(),也就避免了文档冗余和污染 varImg=newImage(), dataURL=''; Img.src=url; Img.onload=function(){//要先确保图片完整获取到,这是个异步事件 varcanvas=document.createElement("canvas"),//创建canvas元素 width=Img.width,//确保canvas的尺寸和图片一样 height=Img.height; canvas.width=width; canvas.height=height; canvas.getContext("2d").drawImage(Img,0,0,width,height);//将图片绘制到canvas中 dataURL=canvas.toDataURL('image/jpeg');//转换图片为dataURL }; }
一个可供随时调用的转换函数完成了,它会在图片被加载后返回一整个dataURL字符串。
完善
onload事件确保了转换任务在加载后执行,却又带来了新问题——dataURL只有在图片加载完成后才会返回,我们无法确定图片什么时候完成加载。如果后续要对dataURL做相关处理(比如传递到其他服务器)的话,添加一个回调是必要的,这能确保后续处理任务在成功得到dataURL之后执行,我们需要修改getBase64():
functiongetBase64(url,callback){//添加一个回调参数 ... Img.onload=function(){ ... canvas.getContext("2d").drawImage(Img,0,0,width,height); dataURL=canvas.toDataURL('image/jpeg'); callback?callback(dataURL):null;//调用回调函数 }; }
在执行时添加回调:
getBase64('//upload.jianshu.io/users/upload_avatars/555630/fdd1b798e6b0.jpg',(dataURL)=>{ console.log(dataURL); });
就是这样,如果不考虑兼容性的话,或许我们可以用promise和generator来实现,再添加一些错误处理就更完美了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。