html结构转图片上传服务器并实现点击复制图片到剪贴板
总结
主要实现了将前端页面上某区域的页面html结构通过html2canvas插件转换成canvas对象,通过canvas对象的toDataURL()方法将其转换为base64编码。获得base64编码后根据接口入参类型转换成file类型或直接上传。亦可通过base64编码利用web剪贴板技术将图片写入剪贴板用于在其他地方粘贴。
背景
根据需求,发起一个协议要生成协议的二维码海报,海报形式如下,为html结构。在已发起模块中,每个协议详情中需要展示自己海报。同时,此二维码海报需点击复制功能,主要用于用户点击复制后在微信等平台粘贴分享。
研究
- 安装html2canvas插件并导入
npm install --save html2canvas
在用到的页面导入 import html2canvas from 'html2canvas'
- 通过html2canvas插件将html结构转为canvas对象进而转为base编码格式
const node = this.$refs['code'] // 需要转换的dom结构
const scale = window.devicePixelRatio // 当前显示设备的物理像素分辨率与CSS像素分辨率之比
html2canvas(node, {
dpi: 300, // 精度,处理模糊问题
useCORS: true, // 允许跨域
scale: scale,
width: 240,
height: 426.55,
backgroundColor: 'rgba(256, 256, 256, 1)',
allowTaint: true,
removeContainer: true // 清除临时创建的克隆dom元素
// eslint-disable-next-line space-before-function-paren
}).then(async (canvas) => {
const base64Img = canvas.toDataURL('image/png') // 通过toDataURL将此canvas对象转成base64编码
const file = this.base64toFile(base64Img, '海报') // 转file
})
- 由于这里的接口入参需要文件类型,base64编码转为file类型
base64toFile(dataBase64, filename = 'file') {
const arr = dataBase64.split(',')
const mime = arr[0].match(/:(.*?);/)[1] // 获取file文件流的type名称
const suffix = mime.split('/')[1] // 获取文件类型
const bstr = window.atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime
})
}
此时已获取到该html结构转换后的图片文件,可直接用于上传接口。
关于将图片写入电脑剪贴板
在上面已经获得了html结构转图片后的base64编码,将其转换成blob对象,再通过剪贴板的navigator.clipboard.write()方法写入
async clipboardImg(url) {
try {
const data = await fetch(url)
const blob = await data.blob()
await navigator.clipboard.write([
new window.ClipboardItem({
[blob.type]: blob
})
])
this.$message.success('复制成功!')
} catch (err) {
this.$message.error('复制失败')
}
}
关于上传图片之后在另一模块中只能拿到图片的httpUrl路径,此时还要实现点击复制功能,实现方法如下
这里显示的海报实际上是一个在线图片(https://xxxxx…xxxx)与上面是一个html结构不同。主要通过创建一个canvas画板,将海报画到画板中,得到海报的canvas对象,调用上面的复制方法。
copyCode(url) {
var canvas = document.createElement('canvas') // 创建一个画板
const image = new Image()
image.setAttribute('crossOrigin', 'Anonymous') // 可能会有跨越问题
image.src = url
image.onload = () => { // img加载完成事件
canvas.width = image.width // 设置画板宽度
canvas.height = image.height // 设置画板高度
canvas.getContext('2d').drawImage(image, 0, 0) // 加载img到画板
const url = canvas.toDataURL('image/png') // 转换图片为dataURL,格式为png
this.clipboardImg(url) // 调用复制方法
}
},