当前位置:首页 > 日记 > 正文

利用canvas中toDataURL | 将转为dataURL | base64的方法详解

利用canvas中toDataURL | 将转为dataURL | base64的方法详解

将图片转为base64的好处

将图片转换为Base64编码,可以让你很方便地在没有上传文件的条件下将图片插入其它的网页、编辑器中。 这对于一些小的图片是极为方便的,因为你不需要再去寻找一个保存图片的地方。

将图片转换成base64编码的,在web网上一般用于小图片上,不仅可以减少图片的请求数量(集合到js、css代码中),还可以防止因为一些相对路径等问题导致图片404错误。

引言

假设一个应用场景:由于某些特殊原因从服务端请求到图片路径,要求通过该路径获取对应图片的 base64 dataURL。在这个场景中,我们首先推断该图片路径是可访问的,同时还需要一种将图片转换到 dataURL 的方法。

我们如何实现它呢?

dataURL

先大致回顾下正统的 dataURL 的语法,这有助于我们检验转换后的内容是否正确。一个完整的 dataURI 应该是这样的:

data:[<mediatype>][;base64],<data>

其中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类型,而这两种类型一般只能通过<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 前必须先确保图片成功加载到,于是.toDataURL()方法应该写在<img>的onload异步事件中。现在就来实现一个功能函数:

 function getBase64(url){  //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染  var Img = new Image(),   dataURL='';  Img.src=url;  Img.onload=function(){ //要先确保图片完整获取到,这是个异步事件   var canvas = 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()

 function getBase64(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.webp',(dataURL)=>{  console.log(dataURL); });

就是这样,如果不考虑兼容性的话,或许我们可以用 promise 和 generator 来实现,再添加一些错误处理就更完美了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

相关文章

Windows 2003邮件服务器配置指南

Windows 2003邮件服务器配置指南

服务器配置,邮件,指南,电脑软件,Windows,邮件服务器的配置同样是企业网络管理中经常要进行的任务之一。与Web网站、FTP站点服务器一样,邮件服务器的配置方案也非常之多,但对于中小型企业说,利用网络操作系统自带的方式进行配置是最经济的。本…

IIS6架设网站常见问题及症状答疑

IIS6架设网站常见问题及症状答疑

网站,症状,常见问题,电脑软件, 很多朋友在用IIS6架网站的时候遇到不少问题,而这些问题有些在过去的IIS5里面就遇到过,有些是新出来的,做了很多次试验,结合以前的排错经验,做出了这个总结,希望能给大家帮上忙。 问题1:未启用父路径 症状举例: S…

完美解决Thinkphp3.2中插入相同数

完美解决Thinkphp3.2中插入相同数

数据,完美,电脑软件,问题描述今天在使用TP3.2插入数据的时候,为了避免插入相同的数据(所谓相同的数据,其主键相同或者是唯一索引的字段相同),我创建的索引如下图,主键索引为自增字段,不可能出现重复,即唯一索引可能会出现重复,我希望的是uid,year,mo…

红帽Linux忘记root密码的解决方法

红帽Linux忘记root密码的解决方法

解决方法,密码,红帽,电脑软件,root,在出现以下画面后按下键盘e键 (图1) 按下后会出现如下画面,在次按下e键,将会出现如图3所示的画面(图2)如图3所示,使用上下键将焦点移动到第2项,如果出现的和本图不一样,就找到有kerner字样的那一行,然后再次按下E键…

PS怎么设计珍珠字效果的字体?

PS怎么设计珍珠字效果的字体?

字体,效果,电脑软件,PS,用PS制作珍珠字的效果,做好之后图片看上去就像是用珍珠摆成的字一样。软件名称:Adobe Photoshop 8.0 中文完整绿色破解版软件大小:150.1MB更新时间:2015-11-041、建立一个100*100的图象文件,用椭圆形选框工具画一个固定大…

angular中实现li或者某个元素点击

angular中实现li或者某个元素点击

方法,元素,两种,电脑软件,angular,本文介绍了angular中实现li或者某个元素点击变色的两种方法,分享给大家,希望对大家有帮助先说一种最直接了当的不需要js控制。方法一:直接在用ng-class就可以控制:<p ng-click="state=1;" ng-class="{activ…

ps怎么设计一个圆形的旅游图标?

ps怎么设计一个圆形的旅游图标?

图标,电脑软件,ps,ps中想要设计一个圆形的旅游图标,该怎么设计呢?下面我们就来看看详细的教程。软件名称:Adobe Photoshop 8.0 中文完整绿色破解版软件大小:150.1MB更新时间:2015-11-041、我们设计整个旅游图标为一个圆形的结构,先从天空开始设计…

javascript中神奇的 Date对象小结

javascript中神奇的 Date对象小结

对象,神奇,电脑软件,javascript,Date,Date 对象算是较常用的对象之一,但很多人完全不会操作,就算一些简单的操作也用 moment 而不自己尝试一下。本次分享下 Date 中的 date 使用技巧,希望能给大家启发。MDN官网介绍setDate() 方法根据本地时间…

PHP基于递归实现的约瑟夫环算法示

PHP基于递归实现的约瑟夫环算法示

算法示例,递归实现,约瑟夫,电脑软件,PHP,本文实例讲述了PHP基于递归实现的约瑟夫环算法。分享给大家供大家参考,具体如下:约瑟夫环问题: 39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓。于是决定了自杀方式…

excel输入带圈数字的方法excel怎么

excel输入带圈数字的方法excel怎么

输入带,数字,方法,电脑软件,excel,  在Excel中录入数据的时候经常需要输入一些带圈的数字,这些数字不是单纯的靠输入法就可以输入的,是要利用Excel中的功能。接下来请欣赏小编给大家网络收集整理的excel输入带圈数字的方法。excel输入带圈…

ubuntu 9.10创建samba错误的解决方

ubuntu 9.10创建samba错误的解决方

解决方法,错误,电脑软件,ubuntu,samba,新建一个文件夹,右键选择属性,并选择share,选择share this folder,点击create按钮,得到如下错误:Failed to execute child process "testparm" (No such file or directory)解决方法如下:sudo cp /usr/bin/…

word2003如何设置页码左右

word2003如何设置页码左右

设置,方法,文档,页码,如何设置,  Word文档中插入页码是办公的基本操作,利用微软Office所提供的强大页码功能,我们可以实现丰富多样的页码格式。下面小编将为大家讲解一下word文档页码左右设置技巧,欢迎大家来到学习。word2003文档设置左右页…