下载的图片已经生成div
图片加载完成事件中完成canvas函数的绘画
<el-image
:src="
locationIP +
'/prod-api/get/detection/img/' +
itemData.img_id +
'?token=' +
token
"
:load="htmlCanvas(itemData)"
>
</el-image>
新建一个文件放置所要整合的div
<template>
<svg :width="context.elWidth" :height="context.elHeight">
<foreignObject
x="0"
:y="0"
:height="context.elHeight"
:width="context.elWidth"
>
<div
style="
/* background: rgba(255, 255, 255, 1); */
width: 100%;
height: 500px;//后来察觉此高度无效
color: black;
font-weight: bold;
font-size: 30px;
border-radius: 10px;
box-sizing: border-box;
/* opacity: 0; */
/* background:rgba(255, 255, 255, 0.6); */
padding-bottom: 20px;
overflow: hidden;
"
>
<div
style="
width: 100%;
background-color: rgba(121,180,242, 0.7);
height: 80px;
padding-left: 10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
line-height: 80px;
text-align: center;
color: #fff;
display: flex;
align-items: center;
box-sizing: border-box;
"
>
<div
style="
width:20px;
height:20px;
border-radius: 50%;
background-color: rgba(244, 197, 59, 1);
"
></div>
<div style="width: 80%; text-align: center">
{{ itemData?.device_name }}
</div>
</div>
<div style="padding-left: 10px; text-align: left;background: rgba(255, 255, 255, 0.6);height: 380px; box-sizing: border-box;border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;">
<div
style="
display: flex;
align-items: center;
padding-top: 10px;
"
>
<p style="width: 160px; text-align: justify">
区 域:
</p>
<p style="height: auto">
{{ itemData?.p_device_name + itemData?.location }}
</p>
</div>
<div style="display: flex; align-items: center; ">
<p style="width: 160px; text-align: justify">拍摄时间:</p>
<p style="height: auto">{{ itemData?.cap_time }}</p>
</div>
<div style="display: flex; align-items: center;">
<p style="width: 160px; text-align: justify">
地 点:
</p>
<p style="height: auto">
{{ itemData?.p_device_name + itemData?.device_name }}
</p>
</div>
</div>
</div>
</foreignObject>
</svg>
</template>
<script>
export default {
name: "svgIndex",
props: {
itemData: {
type: Object,
default: () => {},
},
context: {
type: Object,
default: () => {
return {
width: 0,
height: 0,
elWidth: 700,
elHeight: 500,
};
},
},
},
data() {
return {};
},
};
</script>
<style scoped>
</style>
引入到图片加载事件所在的文件(父组件)中
在setup中的实现函数
const imgUrl = ref("");
const htmlCanvas = (e) => {
// console.log(img)
nextTick(() => {
//原图的请求地址
const temp_src =
locationIP +
"/prod-api/get/detection/img/" +
itemData.img_id +
"?token=" +
token;
let img = new Image();
img.src = temp_src;
img.onload = function () {
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
//根据原图的大小生成画布,为了生成和原图一样分辨率的图片
canvas.width = img.width;
canvas.height = img.height;
canvas.style.width = img.width + "px";
canvas.style.height = img.height + "px";
context.drawImage(img, 0, 0, img.width, img.height);
//将子组件挂载成dom
let svgIndexConstructor = createVNode(svgIndex,{
itemData: itemData,
context: {
width: 0,
height: 0,
elWidth: 700,
elHeight: 500,
},
});
const mountNode = document.createElement("div");
//render函数的作用就是将Notice组件的虚拟DOM转换成真实DOM并插入到mountNode元素里
render(svgIndexConstructor, mountNode);
nextTick(() => {
// console.log(svgIndexConstructor.el);
const down = svgIndexConstructor.el
// const down = instance.vnode.el;
const downCopy = down.cloneNode(true); //深度拷贝原本的dom防止影响原来的dom样式变形
const xmlDom = new XMLSerializer().serializeToString(downCopy); //将设置好颜色的div转为xml
const xml = `<?xml version="1.0" standalone="no"?>\r\n${xmlDom}`; //生成xml文件
// utf-8转换为base64码
const src = `data:image/svg+xml;base64,${window.btoa(
unescape(encodeURIComponent(xml))
)}`;
将div转换成图像
var img2 = new Image();
img2.src = src;
// console.log(divContent)
img2.onload = function () {
const square_y = Number(img.height - 460 - 20);//设置div距离y轴的距离
context.drawImage(img2, 30, square_y, 700, 500);
imgUrl.value = canvas.toDataURL("image/jpeg", 1);
};
});
};
});
};