base64格式: data:image/png;base64,adfsdf...一堆字符
普通小图直接通过image和a标签处理就可以了:
const dataURL = ... // 非png格式的dataURL,如svg
const image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function () {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
const url = canvas.toDataURL('image/png')
const aLink = document.createElement('a')
const event = new MouseEvent('click')
a.download = '下载图片'
a.href = url
a.dispatchEvent(event)
}
image.src = dataURL
但是当图片很大时,使用上述方法会导出失败,windows上会报错:network error,需要改动一下上面的方法:
function base64ToObjectURL (base64) {
const arr = base64.split(',')
const mime = arr[0].replace(/^data:/, '')
const bstr = arr[1]
let n = bstr.length
const u8arr = new Uint8Array(n)
while(n--) {
u8arr[n] = bstr.charCodeAt(n)
}
const blob = new Blob([u8arr], {type: mime})
const objurl = URL.createObjectURL(blob)
return objurl
}
const dataURL = ... // 非png格式的dataURL,如svg
const image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function () {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
const url = canvas.toDataURL('image/png')
const objurl = base64ToObjectURL(url)
const aLink = document.createElement('a')
const event = new MouseEvent('click')
a.download = '下载图片'
a.href = objurl
a.dispatchEvent(event)
URL.revokeObjectURL(objurl)
a.removeAttribute('href')
}
image.src = dataURL
关于html导出为图片,可以看这篇文章: www.zhangxinxu.com/study/20170…
需要注意的是:这里的样式是简单样式,如果样式有带上 > :after 等这类选择器或伪类,导出的图片可能会样式有问题或者直接导出失败,这时候需要把样式内联的方式加到节点上再执行导出
部分dom需要给他加上width,否则可能超出容器,导致导出的图片右边部分可能会被截掉
svg子节点的布局,在浏览器展示上需要在svg中。布局在svg外的部分会被截掉,有种overflow:hidden效果
svg导出为图片,主要是借助了XMLSerializer
const cloneNode = canvasDom.cloneNode(true);
const svgDocType = document.implementation.createDocumentType('svg', '-//W3C//DTD SVG 1.1//EN', 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd');
const svgDoc = document.implementation.createDocument('http://www.w3.org/2000/svg', 'svg', svgDocType);
svgDoc.replaceChild(cloneNode, svgDoc.documentElement);
const svgData = new XMLSerializer().serializeToString(svgDoc);
const dataURL = "data:image/svg+xml;charset=utf8," + encodeURIComponent(svgData);