一. 需求
算法小哥需要一个演示平台,连接相机图片绘制四边形区域,作为摄像头识别的范围,然后选择识别模型(睡觉、抽烟、求救等),播放视频画面,并展示检测结果。
核心需求就是绘制四边形,用户按照顺时针或逆时针方向在图片上单击四个点,在点击第四个点时连成封闭的四边形,四边形区域即为摄像头算法识别的区域。
需求很简单,需要进一步处理的是无论用户从哪里开始点击,绘制完成后需要判断,并整理成左上、左下、右上、右下四个坐标传递给后台;异常处理则是用户有可能会交叉绘制四个点(例如绘制顺序为左上、左下、右上、右下的X形),这样虽然最后判断并整理数据没有问题,但在前端画布上呈现的绘图区域是两个相对的三角形,不符合实际需求;因此如果用户四个点画出X形状,则弹出信息并清除已绘制的点,让用户重画。
测试环境已经关闭,抱歉这里就不放图了,如果感觉比较抽象,可以参考我这篇文章:Vue前端实现在图片上画线, 并将端点坐标传给后端
二. 代码实现
1. 模版
主要是canvas画布:
<div class="canvas-wrap">
<canvas id="imgCanvas" ref="canvaxbox"></canvas>
<!--用来和鼠标进行交互操作的canvas-->
<canvas id="drawCanvas" ref="canvas" :style="{ cursor: isDrawing ? 'crosshair' : 'default' }"> </canvas>
<!--存储已生成的点线,避免被清空-->
<canvas id="saveCanvas" ref="canvasSave"></canvas>
</div>
2. 样式
之前搞过的画布,居然又踩坑,主要是图层的相互覆盖问题;
对于图像尺寸需要先和后台商量好,比如原图1920x1080,后台缩放一半传给我绘图,那么我绘图完成后需要把坐标值x2再传给后台:
.canvas-wrap {
width: 960px;
height: 540px;
min-width: 960px;
min-height: 540px;
// margin: 0px auto;
// background-color: skyblue;
position: relative;
}
#imgCanvas,
#drawCanvas,
#saveCanvas {
background: rgba(255, 0, 255, 0);
position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
width: 960px;
height: 540px;
}
#drawCanvas {
z-index: 2;
}
3. 数据配置、核心逻辑和绘图方法
可能会有用不到的,请自行忽略:
<script>
// 后台接口
import { reqSendCoordinates } from '@/api/SmartSchool/markPhoto'
import { reqSaveModelParam } from '@/api/SmartSchool/detection'
export default {
// 父组件获取并传来的图片url
props: {
imgUrl: {
type: String,
default: () => null,
},
},
data() {
return {
isShow: true,
isMapModalVisible: false,
// imgUrl: require('../test.png'),
// imgUrl: '../960.jpg',
// imgUrl: '',
isDrawing: false, // 是否正在绘制
ratio: 1,
imgWidth: '960px',
imgHeight: '540px',
wrapWidth: '960px',
wrapHeight: '540px',
canvasWidth: '960px',
canvasHeight: '540px',
drawingPoints: [],
drawedPoints: [],
imgCanvas: null,

2375

被折叠的 条评论
为什么被折叠?



