Skip to content

Commit 0738777

Browse files
committed
Added document edge editing for rectification
1 parent 2f857cd commit 0738777

File tree

6 files changed

+125
-19
lines changed

6 files changed

+125
-19
lines changed

src/app/camera-detection/camera-detection.component.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@
3030
top: 60%;
3131
position: absolute;
3232
z-index: 2;
33+
}
34+
35+
button {
36+
margin: 4px;
3337
}

src/app/file-detection/file-detection.component.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
.container {
2222
align-items: center;
23-
border: 3px solid orange;
23+
border: 3px solid rgb(255, 255, 255);
2424
}
2525

26-
/* #normalizedImage {
27-
width: 20vw;
28-
} */
26+
button {
27+
margin: 4px;
28+
}

src/app/file-detection/file-detection.component.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
</div>
1616

1717
<input type="file" title="file" id="file" accept="image/*" (change)="onChange($event)" />
18-
18+
<button (click)="rectify()">Rectify</button>
19+
<button (click)="save()">Save</button>
1920
<div class="container">
2021
<div id="imageview">
2122
<img id="image" alt="" />
22-
<canvas id="overlay"></canvas>
23+
<canvas id="overlay" class="overlay"></canvas>
2324
</div>
2425

25-
<div id="resultview">
26-
<canvas id="normalizedImage"></canvas>
26+
<div id="resultview" class="imageview">
27+
<img id="normalizedImage" alt="" />
2728
</div>
2829

2930
</div>

src/app/file-detection/file-detection.component.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,8 @@ export class FileDetectionComponent implements OnInit {
6969
this.cvr.capture(file, 'NormalizeDocument_Default').then((normalizedImagesResult: CapturedResult) => {
7070
if (normalizedImagesResult.items.length === 0) { return; }
7171
let result = normalizedImagesResult.items[0] as NormalizedImageResultItem;
72-
let image = document.getElementById('normalizedImage') as HTMLCanvasElement;
73-
image.width = result.imageData.width;
74-
image.height = result.imageData.height;
75-
const destinationContext = image.getContext('2d');
76-
destinationContext?.drawImage(result.toCanvas(), 0, 0);
72+
let image = document.getElementById('normalizedImage') as HTMLImageElement;
73+
image.src = result.toImage("image/jpeg").src;
7774
});
7875
}
7976
}
@@ -99,11 +96,7 @@ export class FileDetectionComponent implements OnInit {
9996
if (capturedResult.items.length > 0) {
10097
let result = capturedResult.items[0] as DetectedQuadResultItem;
10198
this.points = result.location.points;
102-
this.overlayManager.drawOverlay(
103-
result.location,
104-
''
105-
);
106-
this.normalize(file, this.points);
99+
this.overlayManager.setPoints(this.points);
107100
}
108101
}
109102
};
@@ -115,4 +108,20 @@ export class FileDetectionComponent implements OnInit {
115108
}
116109
}
117110

111+
async rectify() {
112+
await this.normalize(this.currentFile!, this.points);
113+
}
114+
115+
async save() {
116+
let image = document.getElementById('normalizedImage') as HTMLImageElement;
117+
118+
let imageUrl = image.src;
119+
120+
const a = document.createElement('a');
121+
a.href = imageUrl;
122+
a.download = Date.now() + '';
123+
document.body.appendChild(a);
124+
a.click();
125+
document.body.removeChild(a);
126+
}
118127
}

src/app/overlay.ts

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Quadrilateral } from "dynamsoft-barcode-reader-bundle";
1+
import { Point, Quadrilateral } from "dynamsoft-barcode-reader-bundle";
22

33
export class OverlayManager {
44
overlay: HTMLCanvasElement | undefined;
55
context: CanvasRenderingContext2D | undefined;
6+
globalPoints: Point[] | undefined;
67

78
initOverlay(overlay: HTMLCanvasElement): void {
89
this.overlay = overlay;
@@ -28,6 +29,7 @@ export class OverlayManager {
2829
drawOverlay(localization: Quadrilateral, text: any): void {
2930
if (this.context) {
3031
let points = localization.points;
32+
this.globalPoints = points;
3133
this.context.beginPath();
3234
this.context.moveTo(points[0].x, points[0].y);
3335
this.context.lineTo(points[1].x, points[1].y);
@@ -62,4 +64,94 @@ export class OverlayManager {
6264
this.context.fillText(text, left, top + 50);
6365
}
6466
}
67+
68+
setPoints(points: Point[]): void {
69+
this.globalPoints = points;
70+
this.overlay!.addEventListener("mousedown", (event) => this.updatePoint(event, this.context!, this.overlay!));
71+
this.overlay!.addEventListener("touchstart", (event) => this.updatePoint(event, this.context!, this.overlay!));
72+
this.drawQuad(this.context!, this.overlay!);
73+
}
74+
75+
updatePoint(e: MouseEvent | TouchEvent, context: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {
76+
if (!this.globalPoints) {
77+
return;
78+
}
79+
let globalPoints = this.globalPoints;
80+
function getCoordinates(e: MouseEvent | TouchEvent): Point {
81+
let rect = canvas.getBoundingClientRect();
82+
83+
let scaleX = canvas.clientWidth / canvas.width;
84+
let scaleY = canvas.clientHeight / canvas.height;
85+
86+
let mouseX = (e instanceof MouseEvent ? e.clientX : e.touches[0].clientX);
87+
let mouseY = (e instanceof MouseEvent ? e.clientY : e.touches[0].clientY);
88+
if (scaleX < scaleY) {
89+
mouseX = mouseX - rect.left;
90+
mouseY = mouseY - rect.top - (canvas.clientHeight - canvas.height * scaleX) / 2;
91+
92+
mouseX = mouseX / scaleX;
93+
mouseY = mouseY / scaleX;
94+
}
95+
else {
96+
mouseX = mouseX - rect.left - (canvas.clientWidth - canvas.width * scaleY) / 2;
97+
mouseY = mouseY - rect.top;
98+
99+
mouseX = mouseX / scaleY;
100+
mouseY = mouseY / scaleY;
101+
}
102+
103+
return { x: Math.round(mouseX), y: Math.round(mouseY) };
104+
}
105+
106+
let delta = 10;
107+
let coordinates = getCoordinates(e);
108+
let ref = this;
109+
for (let i = 0; i < globalPoints.length; i++) {
110+
if (Math.abs(globalPoints[i].x - coordinates.x) < delta && Math.abs(globalPoints[i].y - coordinates.y) < delta) {
111+
canvas.addEventListener("mousemove", dragPoint);
112+
canvas.addEventListener("mouseup", releasePoint);
113+
canvas.addEventListener("touchmove", dragPoint);
114+
canvas.addEventListener("touchend", releasePoint);
115+
116+
function dragPoint(e: MouseEvent | TouchEvent) {
117+
coordinates = getCoordinates(e);
118+
globalPoints[i].x = coordinates.x;
119+
globalPoints[i].y = coordinates.y;
120+
ref.drawQuad(context, canvas);
121+
}
122+
123+
function releasePoint() {
124+
canvas.removeEventListener("mousemove", dragPoint);
125+
canvas.removeEventListener("mouseup", releasePoint);
126+
canvas.removeEventListener("touchmove", dragPoint);
127+
canvas.removeEventListener("touchend", releasePoint);
128+
}
129+
130+
break;
131+
}
132+
}
133+
}
134+
135+
drawQuad(context: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {
136+
let globalPoints = this.globalPoints;
137+
if (!globalPoints || globalPoints.length < 4) {
138+
return;
139+
}
140+
141+
context.clearRect(0, 0, canvas.width, canvas.height);
142+
context.strokeStyle = "#00ff00";
143+
context.lineWidth = 2;
144+
for (let i = 0; i < globalPoints.length; i++) {
145+
context.beginPath();
146+
context.arc(globalPoints[i].x, globalPoints[i].y, 5, 0, 2 * Math.PI);
147+
context.stroke();
148+
}
149+
context.beginPath();
150+
context.moveTo(globalPoints[0].x, globalPoints[0].y);
151+
context.lineTo(globalPoints[1].x, globalPoints[1].y);
152+
context.lineTo(globalPoints[2].x, globalPoints[2].y);
153+
context.lineTo(globalPoints[3].x, globalPoints[3].y);
154+
context.lineTo(globalPoints[0].x, globalPoints[0].y);
155+
context.stroke();
156+
}
65157
}

src/assets/images/default.png

4.59 KB
Loading

0 commit comments

Comments
 (0)