价值
图片大小小于 10 k 时会走 base64。即不会被拷贝到 public 文件夹下,而是以 base64 的资源存在。
这是从umi 2.x官网摘抄的一句话,对于一些小图片也没有必要做一个单独的静态资源来存储,毕竟转化为base64以后长度也是完全可以接受的。
又或者当我们需要导出一个html文件,而这个html文件中存在图片,或者我们想把当前的html页面以word的格式导出。前着还可以考虑用把html文件和引用的静态图片打包成一个压缩包的形式导出,但后者却很难实现。如果我们可以把图片集成到html中,是不是只导出html就OK了~
什么是base64?
不多赘述
衍生出来的问题,如何转化以及如何使用。
如何把图片转化为base64
第一种: 如果我们画了一些cavas图,例如使用antv或者echarts画了一些图标,我们可以使用canvas的toDataUrl()来直接转化:
const dataURL = document.getElementById('canvasId').toDataURL()
第二种:对于正常的png,jpg这种图片的转化其实可以参考第一种,先将图片转化为canvas,然后再toDataUrl()。
const img = new Image()
img.crossOrigin = ''
img.src = src
img.onload = function () {
const canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
const ctx = canvas.getContext('2d')
ctx?.drawImage(img, 0, 0, img.width, img.height)
const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
const dataURL = canvas.toDataURL('image/' + ext)
第三种: 在node中使用toString('base64'),原理利用node的fs模块readFileSync读取图片,然后再将读取到的内容转换成base64格式。
const data = fs.readFileSunc(图片路径)
const dataURL = Buffer.from(data).toString('base64')
第四种: 利用FileReader对象的readAsDataURL方法,readAsDataURL会以base64进行编码。
const getBase64Image = src => {
return new Promise(resolve => {
let xhr = new XMLHttpRequest()
xhr.open('get', src, true)
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status == 200) {
let blob = this.response
let oFileReader = new FileReader()
oFileReader.onloadend = function (e) {
const base64 = e.target.result
resolve(base64)
}
oFileReader.readAsDataURL(blob)
}
}
xhr.send()
})
如何使用得到的base64。
使用的时候对于获取的base64值并不是都可以直接复制给src属性的。Buffer.from(data).toString('base64')转化出来的base64值就不可以直接赋值给图片的src属性。核心在于img标签的src值的格式必须为:
data:image/png;base64,base64数据
也就是说:
<img src=`data:image/png;base64,${base64数据}`/>
<img src="'data:image/png;base64,'+base64数据" />
所以小伙伴们转出来的base64值最好看看是不是符合这个格式啦~