邵佳豪 3 years ago
parent
commit
90f8142e1c
  1. 12
      src/app/system-management/image-label2/image-label2.component.html
  2. 1
      src/app/system-management/image-label2/image-label2.component.scss
  3. 291
      src/app/system-management/image-label2/image-label2.component.ts

12
src/app/system-management/image-label2/image-label2.component.html

@ -1,10 +1,14 @@
<div class="box">
<nz-page-header class="site-page-header" (nzBack)="goback()" nzBackIcon nzSubtitle="返回上一页"></nz-page-header>
<div class="btnbox">
<button nz-button nzType="primary">获取标注底图/更新摄像头图片</button>
<button nz-button [ngClass]="{selectBtn: markType}" (click)="markType = true;">标注监控区域</button>
<button nz-button [ngClass]="{selectBtn: !markType}" (click)="markType = false;">标注禁止区域</button>
<button nz-button nzType="primary">保存</button>
<label class="leftTitle" *ngIf="markType === 1">进出口</label>
<label class="leftTitle" *ngIf="markType === 3">卸油区</label>
<label class="leftTitle" *ngIf="markType === 4">便利店</label>
<!-- <button nz-button nzType="primary">获取标注底图/更新摄像头图片</button> -->
<button nz-button *ngIf="markType === 3" [ngClass]="{selectBtn: isDrawArrow}" (click)="isDrawArrow = true;">箭头方向标绘</button>
<button nz-button *ngIf="markType === 3" [ngClass]="{selectBtn: !isDrawArrow && oilUnloadingArea}" (click)="isDrawArrow = false; oilUnloadingArea = true;">泄油管区域</button>
<button nz-button *ngIf="markType === 3" [ngClass]="{selectBtn: !isDrawArrow && !oilUnloadingArea}" (click)="isDrawArrow = false; oilUnloadingArea = false;">静电接地仪</button>
<button nz-button nzType="primary" (click)="save()">保存</button>
<button nz-button nzType="primary" nzDanger (click)="clearCanvas()">清空</button>
</div>
<div class="imgbox">

1
src/app/system-management/image-label2/image-label2.component.scss

@ -24,6 +24,7 @@
button {
margin-right: 6px;
}
.leftTitle{ line-height: 32px; padding: 0 20px; }
}
.imgbox,

291
src/app/system-management/image-label2/image-label2.component.ts

@ -12,8 +12,7 @@ export class ImageLabel2Component implements OnInit {
imgItem: any;
canvasWidth: number = 0;
canvasHeight: number = 0;
copyCanvas: any;
markType: boolean = true; //标注type
copyCanvas: any; //拷贝 canvas底图
//返回上一步路由
goback() {
@ -30,6 +29,18 @@ export class ImageLabel2Component implements OnInit {
}, 0)
}
//保存
save() {
if (this.markType === 1) {
console.log("多边形",this.points)
} else if (this.markType === 3) {
console.log("箭头",this.arrowPoints)
console.log("矩形",this.oblongPoints)
} else if (this.markType === 4) {
console.log("箭头",this.arrowPoints)
}
}
//初始化背景图
initBackgroundImg() {
let canvas = document.getElementById('canvas') as any;
@ -76,53 +87,218 @@ export class ImageLabel2Component implements OnInit {
//线段的点的集合
points = [];
points2 = [];
//可拖动圆圈的点的集合
circles = [];
circles2 = [];
//整体移动点位
allpoints = [];
allpoints2 = [];
isDragging = false
//是否在绘制区域内
isInOut = false
markType: number = 3; //1=进出口,3=卸油区,4=便利店,
isDrawArrow: boolean = true; //绘制type 箭头/矩形
oilUnloadingArea: boolean = true; //卸油区type 泄油管区域/静电接地仪
//记录鼠标点击位置
downx = 0
downy = 0
downx = 0;
downy = 0;
//清空画布
clearCanvas() {
let istrue = confirm("清除属于不可逆操作,你是否继续?");
if (!istrue) {
return
}
// 清空标绘箭头
this.arrowPoints = [];
// 清空标绘箭头
// 清空标绘矩形
this.oblongPoints = [];
// 清空标绘矩形
// 清空标绘多边形
this.points = [];
this.points2 = [];
this.circles = [];
this.circles2 = [];
this.allpoints = [];
this.allpoints2 = [];
// 清空标绘多边形
let canvas = document.getElementById('canvas') as any;
let context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas? context.putImageData(this.copyCanvas, 0, 0) : null;
}
//初始化 canvas画布 点击事件
//初始化 canvas画布 监听事件
initCanvasEvent(canvas) {
let context = canvas.getContext('2d');
// let html = document.documentElement
// let boxDiv = document.getElementsByClassName("canvasDialog")[0]
canvas.onmousedown = (e)=>{
this.canvasClickEvent(e,canvas,context);
canvas.onmousedown = (e)=>{ //鼠标按下事件
var clickX = e.pageX - canvas.offsetLeft;
var clickY = e.pageY - canvas.offsetTop;
this.downx = clickX
this.downy = clickY
if (this.markType === 1) { //进出口
this.drawPolygon(clickX,clickY,canvas,context); //绘制多边形
} else if (this.markType === 3 || this.markType === 4) { //卸油区/便利店
//开始绘制
context.beginPath();
context.moveTo(clickX,clickY);
context.strokeStyle = "green";
context.lineWidth = 3;
canvas.onmousemove = (ev)=>{ //鼠标移动事件
var moveX = ev.pageX - canvas.offsetLeft;
var moveY = ev.pageY - canvas.offsetTop;
if (this.isDrawArrow) { //绘制 箭头
context.lineTo(moveX,moveY);
context.stroke();
} else { //绘制 矩形
this.drawOblong(this.oblongPoints,context)
context.strokeStyle = this.oilUnloadingArea? "green" : "red";
let element = this.getOblongInfo(this.downx,this.downy,moveX,moveY)
context.strokeRect(element.x,element.y,element.width,element.height);
}
}
}
}
canvas.onmouseup = (e)=>{ //鼠标松开事件
canvas.onmousemove = (ev)=>{ //鼠标移动事件
return false;
}
if (this.markType != 3 && this.markType != 4) {
return
}
var upX = e.pageX - canvas.offsetLeft;
var upY = e.pageY - canvas.offsetTop;
if (this.isDrawArrow) { //绘制 箭头
let point = {
startX: this.downx,
startY: this.downy,
endX: upX,
endY: upY,
}
this.arrowPoints.push(point);
this.drawLine(this.arrowPoints,context)
} else { //绘制 矩形
let point = this.getOblongInfo(this.downx,this.downy,upX,upY)
this.oblongPoints.push(point)
this.drawOblong(this.oblongPoints,context)
}
};
}
arrowPoints = []; //箭头的点的集合
//canvas 绘制直线
drawLine(pointsList, context, isRepeat: boolean = false) {
context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.copyCanvas? context.putImageData(this.copyCanvas, 0, 0) : null;
if (this.markType === 3 && !isRepeat) { //同时绘制 矩形
this.oblongPoints.forEach(element => {
context.strokeStyle = element.oilUnloadingArea? "green" : "red";
context.lineWidth = 3;
context.strokeRect(element.x,element.y,element.width,element.height);
});
}
pointsList.forEach((item,index)=>{
if ((index+1)%2 === 0) {
this.drawArrow(item.startX,item.startY,item.endX,item.endY,30,10,3,'green',context)
} else {
context.beginPath();
context.moveTo(item.startX,item.startY);
context.strokeStyle = "green";
context.lineWidth = 3;
context.lineTo(item.endX,item.endY);
context.stroke();
}
})
}
//canvas 绘制箭头
drawArrow(fromX, fromY, toX, toY, theta, headlen, width, color, ctx) {
// fromX, fromY:起点坐标(也可以换成p1,只不过它是一个数组)
// toX, toY:终点坐标 (也可以换成p2,只不过它是一个数组)
// theta:三角斜边一直线夹角
// headlen:三角斜边长度
// width:箭头线宽度
// color:箭头颜色
theta = typeof(theta) != 'undefined' ? theta : 30;
headlen = typeof(theta) != 'undefined' ? headlen : 10;
width = typeof(width) != 'undefined' ? width : 1;
color = typeof(color) != 'undefined' ? color : '#000';
// 计算各角度和对应的P2,P3坐标
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
angle1 = (angle + theta) * Math.PI / 180,
angle2 = (angle - theta) * Math.PI / 180,
topX = headlen * Math.cos(angle1),
topY = headlen * Math.sin(angle1),
botX = headlen * Math.cos(angle2),
botY = headlen * Math.sin(angle2);
ctx.save();
ctx.beginPath();
var arrowX = fromX - topX,
arrowY = fromY - topY;
ctx.moveTo(arrowX, arrowY);
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
arrowX = toX + topX;
arrowY = toY + topY;
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(toX, toY);
arrowX = toX + botX;
arrowY = toY + botY;
ctx.lineTo(arrowX, arrowY);
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.stroke();
ctx.restore();
}
oblongPoints = []; //矩形的点的集合
//获取 矩形左上角点位/宽高
getOblongInfo(startX,startY,endX,endY) {
let point = {
x: 0,
y: 0,
width: 0,
height: 0,
oilUnloadingArea: this.oilUnloadingArea,
}
if (startX > endX) {
point.x = endX
point.width = startX - endX
} else {
point.x = startX
point.width = endX - startX
}
if (startY > endY) {
point.y = endY
point.height = startY - endY
} else {
point.y = startY
point.height = endY - startY
}
return point
}
//canvas 绘制矩形
drawOblong(oblongList, context) {
context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.copyCanvas? context.putImageData(this.copyCanvas, 0, 0) : null;
if (this.markType === 3) { //同时绘制 直线箭头
this.drawLine(this.arrowPoints,context,true)
}
oblongList.forEach(element => {
context.strokeStyle = element.oilUnloadingArea? "green" : "red";
context.lineWidth = 3;
context.strokeRect(element.x,element.y,element.width,element.height);
});
}
//canvas 点击事件 标注
canvasClickEvent(e, canvas, context) {
var clickX = e.pageX - canvas.offsetLeft;
var clickY = e.pageY - canvas.offsetTop;
this.downx = clickX
this.downy = clickY
points = []; //线段的点的集合
circles = []; //可拖动圆圈的点的集合
allpoints = []; //整体移动点位
isDragging = false; //是否可拖拽
isInOut = false; //是否在绘制区域内
//canvas 绘制多边形
drawPolygon(clickX, clickY, canvas, context) {
if (this.isInt(clickX, clickY)) {
this.isInOut = true
return
@ -131,10 +307,9 @@ export class ImageLabel2Component implements OnInit {
}
let index
let beforeCircles = this.markType? this.circles: this.circles2
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < beforeCircles.length; i++) {
let circle = beforeCircles[i];
for (var i = 0; i < this.circles.length; i++) {
let circle = this.circles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2));
@ -148,32 +323,27 @@ export class ImageLabel2Component implements OnInit {
}
}
//如果点击新的位置,则进入下面的代码,绘制点
//context.clearRect(0, 0, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
this.copyCanvas? context.putImageData(this.copyCanvas, 0, 0) : null;
//遍历数组画圆
var circle = {
x: clickX,
y: clickY,
radius: 10,
color: "blue",
radius: 5,
color: "white",
isSelected: false, //拖拽点的标记
};
if (this.markType) {
this.circles.push(circle);
this.allpoints = JSON.parse(JSON.stringify(this.circles))
this.circles[0].color = "green";
} else {
this.circles2.push(circle);
this.allpoints2 = JSON.parse(JSON.stringify(this.circles2))
this.circles2[0].color = "red";
}
for (var i = 0; i < beforeCircles.length; i++) {
let circle = beforeCircles[i];
this.circles.push(circle);
this.allpoints = JSON.parse(JSON.stringify(this.circles))
this.circles[0].color = "white";
for (var i = 0; i < this.circles.length; i++) {
let circle = this.circles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = "black";
context.strokeStyle = "red";
context.fill();
context.stroke();
}
@ -182,36 +352,31 @@ export class ImageLabel2Component implements OnInit {
x: clickX,
y: clickY,
};
this.markType? this.points.push(point) : this.points2.push(point)
this.points.push(point)
context.beginPath();
context.lineWidth = 3;
//从起始点开始绘制
let beforePoint = this.markType? this.points: this.points2
context.moveTo(beforePoint[0].x, beforePoint[0].y);
for (var i = 0; i < beforePoint.length; i++) {
context.lineTo(beforePoint[i].x, beforePoint[i].y);
context.moveTo(this.points[0].x, this.points[0].y);
for (var i = 0; i < this.points.length; i++) {
context.lineTo(this.points[i].x, this.points[i].y);
}
context.closePath()
context.fillStyle = "rgb(2,100,30)";
context.fill();
context.strokeStyle = "#9d4dca";
//ontext.fillStyle = "rgb(2,100,30)";
//context.fill();
context.strokeStyle = "green";
context.stroke();
}
//判断点位是否在图形区域内
isInt(x, y) {
if (this.markType && !this.points[2]) {
return
}
if (!this.markType && !this.points2[2]) {
if (!this.points[2]) {
return
}
var pt = {
x: x,
y: y
}
var poly = this.markType? this.points : this.points2;
return this.PointInPoly(pt, poly)
return this.PointInPoly(pt, this.points)
}
//射线法判断点位

Loading…
Cancel
Save