问题场景
在大屏项目里,需要对设计好的大屏进行生成图片和保存数据时保存一张截图作为管理页面的封面,由于有很多图表组件的渲染涉及到 img 标签,比如地图组件或轮播图插件,当他们使用不同域的资源,在生成图片时,调用canvas的toDataURL时就会出现代码执行失败的情况。
试过网上提供的其他方案例如给img标签添加 crossorigin = ‘anonymous’ 和给img标签的src加上随机数,这两个方案对于我使用html-to-image插件来生成图片都没有解决问题。
解决方案
第一种:封装一个img组件,内部将img的资源转成base64进行渲染
<template>
<img
v-if="innerSrc"
class="base64-image"
v-bind="$attrs"
:src="innerSrc"
alt=""
v-on="$listeners"
>
</template>
<script>
export default {
name: 'Base64Image',
props: {
src: {
type: String,
default: ''
}
},
mixins: [],
data () {
return {
innerSrc: ''
}
},
computed: {},
watch: {
src: {
immediate: true,
handler (val) {
this.toImage(val)
}
}
},
created () {},
mounted () {
this.toImage(this.src)
},
methods: {
getBase64Image (src) {
// eslint-disable-next-line
if (!src) return Promise.reject('未提供图像源')
return new Promise((resolve, reject) => {
const img = new Image()
img.crossOrigin = 'Anonymous'
img.onload = function () {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.height = img.height
canvas.width = img.width
ctx.drawImage(img, 0, 0)
const dataURL = canvas.toDataURL('image/png')
resolve(dataURL)
}
img.onerror = function () {
// eslint-disable-next-line
reject('加载图像失败')
}
img.src = src
})
},
async toImage (src) {
try {
this.innerSrc = await this.getBase64Image(src)
} catch (error) {
console.error('将图像转换为base64时出错:', error)
}
}
}
}
</script>
<style lang="scss" scoped>
/* Your styles here */
</style>
第二种:重新请求图片资源,不使用本地缓存资源
因为项目里生成图片的操作使用的html-to-image插件,这里提供与它相关代码
const node = document.querySelector('')// 获
版权归原作者 -xxwu 所有, 如有侵权,请联系我们删除。