vue-picture-bd-marker 图片添加标注

文档地址: https://vmarker.sagocloud.com/about/?spm=a2c6h.24755359.0.0.1b6441e4HwmruJ

实现效果: 

 

 清空画布: this.$refs['aiPanel-editor'].clearData()

<template>
    <div v-loading="loading" class="markBox"> 
        <div class="imgbox" id="imgbox" ref="at">
            <ui-marker
                ref="aiPanel-editor"
                class="ai-observer"
                v-bind:uniqueKey="uuid"
                :ratio="9/ 16"
                @vmarker:onAnnoSelected="onAnnoSelected"
                @vmarker:onAnnoAdded="onAnnoAdded"
                @vmarker:onUpdated="onUpdated"
                @vmarker:onReady="onReady"
                @vmarker:onImageLoad="onImageLoad"
                @vmarker:onDrawOne="onDrawOne(1)"
                v-bind:readOnly="readOnly"
                v-bind:imgUrl="currentImage"
            >
            </ui-marker>
        </div>

        <div class="btnBox">
            <el-button class="diaWidth" @click="cancel"  style="margin-right:20px">取消</el-button>
            <el-button class="diaWidth" @click="toImage" type="primary">添加标注</el-button>
        </div>
     //选中标注区域在对应区域下展示select选择要标注的内容 <div v-if="markSelect" class="addMark" :style="{left: tranLeft, top: tranTop}"> <el-select v-model="text" allow-create filterable default-first-option @change="markChange" size="small" style="width:100%" placeholder="请选择"> <el-option v-for="(item,index) in list" :key="index" :label="item.content" :value="item.content"> </el-option> </el-select> </div> </div> </template>

 

import { AIMarker } from "Vue-Picture-BD-Marker";
import html2canvas from "html2canvas";
export default {
    components: { "ui-marker": AIMarker, html2canvas },
    data(){
        uuid: "0da9130",
        readOnly: false, //是否只读 
        currentImage: '',
        blist:[],
        text:'',
        markSelect: false,
        total: 0,
        tranLeft: '',
        tranTop: '',    
    },
    watch:{
     //选中select下拉框中的值时 text(val){
if(this.uuid!=''){ let blist = this.blist blist.forEach(i => { if(this.uuid == i.uuid){ this.$refs['aiPanel-editor'].getMarker().setTag({ tagName: this.text, tag: "0x0001" }); i.tagName = this.text } }); this.blist = blist this.dialogVisible = false this.uuid = ''this.text = '' } }, }, methods: { //生成图片 toImage() { // 没有标注提示 if(this.blist.length == 0){ this.$message({ message: '请选择标注', type: "error", }); return } this.loading = true // 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等 html2canvas(this.$refs.at, { backgroundColor: null, useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题 }).then((canvas) => { let quality = 0.2; let url = canvas.toDataURL("image/jpeg",quality); this.htmlUrl = url; let files = this.base64toFile(url) let formData = new FormData(); formData.append("HotelId", this.hotelid); formData.append("file", files); // 把生成的base64位图片上传到服务器,生成在线图片地址 api_UploadImg(formData) .then((res) => { this.loading = false }) .catch((error) => { }); }); }, // base64转文件流
     // html2canvas将div转成图片返回的是base64格式的,上传标注图片是需将base64转成文件流
base64toFile (dataurl, filename = 'file') { let arr = dataurl.split(',') let mime = arr[0].match(/:(.*?);/)[1] let suffix = mime.split('/')[1] let bstr = atob(arr[1]) let n = bstr.length let u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], `${filename}.${suffix}`, { type: mime }) }, onAnnoSelected(e) { this.uuid = e.uuid }, onAnnoAdded(e) { // console.log("添加选框", e); this.dialogVisible = true this.uuid = e.uuid
        //选中区域后展示select,在对应的区域下方
this.markSelect = true this.tranLeft = Number(e.position.x.replace('%',''))/100 * document.querySelector('.imgbox').offsetWidth + 'px' this.tranTop = Number(e.position.y1.replace('%',''))/100 * document.querySelector('.imgbox').offsetHeight + 20 + 'px'
        //限制标注个数超过5个时隐藏select if(this.total > 5){ this.markSelect = false } }, onUpdated(e) { // console.log("选框位置或者标框属性发生改动", e); this.blist = e this.uuid = '' this.text = '' // 限制标注个数 this.total = 0 const markBox = document.getElementById('imgbox') const markers = markBox.querySelectorAll('.annotation') for (let i = 0; i < markers.length; i++) { if (markers[i].clientWidth !== 0) { this.total++ } if (this.total > 5) { this.$message.warning('最多只可标记五处!') markers[i].remove() } }
       //如果有重复的标注时新添加的标注覆盖已有的 let arr1
= [] let peon = e.reduce((cur,next) => { let index = cur.findIndex(item=> item.tagName == next.tagName) if(index != -1){ arr1.push(cur[index]) cur.splice(index, 1) } cur.push(next) return cur; },[]) this.blist = peon e = peon // 重复项新的替换旧的 for(var i = 0; i < markers.length; i++){ let arr = e.findIndex(item=>item.uuid == markers[i].getAttribute('data-uuid')) // console.log(arr) if(arr == -1){ markers[i].remove() } } },

 

posted @ 2022-07-15 11:28  番茄西红柿u  阅读(4628)  评论(3编辑  收藏  举报