18910140161

用canvas的toDataURL()将图片转为dataURL(base64)

顺晟科技

2021-06-16 10:40:40

235

假设一个应用场景:由于一些特殊原因,请求从服务器到图片的路径(图片存储在服务器上),需要通过这个路径获取对应图片的base64 dataURL。在这个场景中,我们首先推断图片路径是可访问的,同时我们需要一个方法来将图片转换成dataURL。怎么才能做到?

数据URL

首先,对传统的dataURL语法的总体回顾将有助于我们检查转换后的内容是否正确。完整的数据URI应该如下所示:

data :[media type][;base64],数据

Mediatype声明文件类型并遵循MIME规则,例如“image/png”和“text/plain”。然后是编码类型,这里我们只涉及base64;然后是文件的编码内容。我们经常在HTML中看到,img标签的src会这样写:

src=' data : image/gif;base64,r0lgoddhmaawapaaaaaaaaaaaaaap///ywaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

这个img指的是base64编码的dataURL,只要浏览器支持,就可以解码成声明格式的图片并呈现。toDataURL()

这是一个函数,FileReader对象也有类似的方法,比如。readAsDataURL()。但是,它只接受文件或blob类型,这两种类型只能通过input[type=file]元素的files属性获得,或者可以使用Blob()构造函数手动创建一个新对象。尴尬的是,我们目前只有图片路径,受制于浏览器的安全策略。input[type=file]的files属性是只读的,而Blob()构造函数只接受文件的内容,两种方式都不能通过图片路径直接获取。上面假设的应用场景迫使我们首先考虑如何通过路径获取图片内容。Img还可以,可以画成画布,正好有。toDataURL()方法。

一切准备就绪。我们只需要把img得到的图片放在画布上,然后用。toDataURL(),然后我们就可以得到base64编码的DataURL了。看看这个方法的语法:

canvas . todaytaurl([type,encoderOptions]);

Canvas是DOM元素的画布对象;参数类型指定图片类型,如果不支持指定类型,则默认值改为image/png;EncoderOptions可以为image/jpeg或image/webp类型的图像设置图像质量,值为0-1,将使用默认值0.92。

需要注意的是,图片加载是异步的,在转换成dataURL之前必须保证图片加载成功,否则可能无法让canvas立即执行画图,导致转换dataURL失败。因此。toDataURL()方法应该写在img的onload事件中,以保证图片下载后画布绘制开始。幸运的是。drawImage()方法是同步的,后续操作,如。toDataURL(),只有在画布绘制完成后才会执行。现在让我们实现一个函数:

函数getBase64(url){

//构造函数创建的img实例在给出src值后会立即下载图片。与createElement()相比,它节省了append(),避免了文档冗余和污染

var Img=new Image(),

dataURL=

Img.src=url

Img.onload=function(){ //保证图片获取完整是异步事件。

var canvas=document . create element(' canvas '),//创建一个canvas元素

Width=Img.width,//确保画布与图片大小相同

height=Img.height

canvas.width=width

canvas.height=height

canvas.getContext('2d ')。drawImage(Img,0,0,宽度,高度);//将图片画成画布

dataURL=canvas . TotaToul(' image/JPEG ');//将图片转换为dataURL

};

}

一个可以随时调用的转换函数完成,加载图片后会返回一个完整的dataURL字符串。

改善

Onload事件保证了图片加载后执行转换任务,但也带来了新的问题。图片加载后才会返回——dataURL,所以我们无法准确得到图片加载的时间。如果以后要处理数据URL(比如传输到其他服务器),需要添加回调,这样可以保证在成功获取数据URL后,后续的处理任务会被执行。让我们修改getBase64():

函数getbase64 (URL,回调){//添加回调参数

.

Img.onload=function(){

.

canvas.getContext('2d ')。drawImage(Img,0,0,宽度,高度);

dataURL=canvas . TotaToul(' image/JPEG ');

callbackcallback(DataURL);//调用回调函数

};

}

在执行时添加回调:

getBase64('//upload . jishu . io/users/upload _ availates/555630/fdd1 b 798 e6b 0 . jpg ',(dataURL)={

console . log(DataURL);

});

就是这样。如果不考虑兼容性,也许可以用promise和generator来实现,加上一些错误处理会更完善。

我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航