jscanify 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/script.js CHANGED
@@ -1,43 +1,42 @@
1
- let loadedOpenCV = false
2
-
3
- const openCvURL = "https://docs.opencv.org/4.7.0/opencv.js"
4
-
5
- function loadOpenCV(onComplete) {
6
- if (loadedOpenCV) {
7
- onComplete()
8
- } else {
9
- $('#demo-result').text('Loading OpenCV...')
10
- const script = document.createElement("script")
11
- script.src = openCvURL
12
-
13
- script.onload = function () {
14
- setTimeout(function () {
15
- onComplete()
16
- }, 1000)
17
- loadedOpenCV = true
18
- }
19
- document.body.appendChild(script)
20
- }
21
- }
22
-
23
- const scanner = new jscanify()
24
- $('#demo-images .image-container').click(function () {
25
- $('.image-container.selected').removeClass('selected')
26
- $(this).addClass('selected')
27
- const imageSrc = $(this).find('img').data('url')
28
- loadOpenCV(function () {
29
- $('#demo-result').empty()
30
-
31
- const newImg = document.createElement("img")
32
- newImg.src = imageSrc
33
-
34
- newImg.onload = function(){
35
- scanner.extractPaper(newImg, 386, 500, (resultCanvas) => {
36
- $('#demo-result').append(resultCanvas);
37
-
38
- const highlightedCanvas = scanner.highlightPaper(newImg)
39
- $('#demo-result').append(highlightedCanvas);
40
- });
41
- }
42
- })
1
+ let loadedOpenCV = false
2
+
3
+ const openCvURL = "https://docs.opencv.org/4.7.0/opencv.js"
4
+
5
+ function loadOpenCV(onComplete) {
6
+ if (loadedOpenCV) {
7
+ onComplete()
8
+ } else {
9
+ $('#demo-result').text('Loading OpenCV...')
10
+ const script = document.createElement("script")
11
+ script.src = openCvURL
12
+
13
+ script.onload = function () {
14
+ setTimeout(function () {
15
+ onComplete()
16
+ }, 1000)
17
+ loadedOpenCV = true
18
+ }
19
+ document.body.appendChild(script)
20
+ }
21
+ }
22
+
23
+ const scanner = new jscanify()
24
+ $('#demo-images .image-container').click(function () {
25
+ $('.image-container.selected').removeClass('selected')
26
+ $(this).addClass('selected')
27
+ const imageSrc = $(this).find('img').data('url')
28
+ loadOpenCV(function () {
29
+ $('#demo-result').empty()
30
+
31
+ const newImg = document.createElement("img")
32
+ newImg.src = imageSrc
33
+
34
+ newImg.onload = function(){
35
+ const resultCanvas = scanner.extractPaper(newImg, 386, 500);
36
+ $('#demo-result').append(resultCanvas);
37
+
38
+ const highlightedCanvas = scanner.highlightPaper(newImg)
39
+ $('#demo-result').append(highlightedCanvas);
40
+ }
41
+ })
43
42
  })
@@ -0,0 +1,148 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <script
5
+ async
6
+ src="https://www.googletagmanager.com/gtag/js?id=G-32CWY3SB1G"
7
+ ></script>
8
+ <script>
9
+ function gtag() {
10
+ dataLayer.push(arguments);
11
+ }
12
+ (window.dataLayer = window.dataLayer || []),
13
+ gtag("js", new Date()),
14
+ gtag("config", "G-32CWY3SB1G");
15
+ </script>
16
+ <meta charset="UTF-8" />
17
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
19
+ <title>jscanify debugger tool</title>
20
+ <meta
21
+ name="description"
22
+ content="A debugging tool for developers to test jscanify."
23
+ />
24
+ <meta property="og:title" content="jscanify debugger tool" />
25
+ <meta
26
+ property="og:description"
27
+ content="A debugging tool for developers to test jscanify."
28
+ />
29
+ <meta
30
+ property="og:url"
31
+ content="https://colonelparrot.github.io/jscanify/tester.html"
32
+ />
33
+ <meta
34
+ property="og:image"
35
+ content="https://colonelparrot.github.io/jscanify/images/logo.png"
36
+ />
37
+ <meta property="og:locale" content="en_US" />
38
+ <link rel="icon" type="image/x-icon" href="favicon.ico" />
39
+ <style>
40
+ html,
41
+ body {
42
+ margin: 0;
43
+ }
44
+ * {
45
+ font-family: system-ui;
46
+ }
47
+
48
+ h1,
49
+ h2,
50
+ h3 {
51
+ font-weight: 400;
52
+ }
53
+
54
+ img,
55
+ canvas {
56
+ max-height: 400px;
57
+ max-width: 400px;
58
+ }
59
+
60
+ #results > div {
61
+ margin: 20px;
62
+ margin-top: 0;
63
+ }
64
+ </style>
65
+ </head>
66
+ <body>
67
+ <div style="padding: 30px">
68
+ <h1 style="margin: 0">jscanify debugging tool</h1>
69
+ <h2 style="margin-top: 10px">
70
+ A tool for developers to test jscanify on test images
71
+ </h2>
72
+
73
+ <h3 style="margin-bottom: 10px">Upload your image:</h3>
74
+ <input
75
+ type="file"
76
+ id="fileInput"
77
+ accept="image/png, image/gif, image/jpeg"
78
+ />
79
+
80
+ <div id="result" style="margin-top: 50px; display: none">
81
+ <h2 style="margin-bottom: 0; margin-left: 20px">Result</h2>
82
+ <div style="display: flex; flex-wrap: wrap" id="results">
83
+ <div>
84
+ <h3>Original image</h3>
85
+ <img id="orig" />
86
+ </div>
87
+ <div id="highlighted">
88
+ <h3>Highlighted Paper</h3>
89
+ </div>
90
+ <div id="extracted">
91
+ <h3>Extracted Paper</h3>
92
+ </div>
93
+ <div id="cornerPts">
94
+ <h3>Corner Points</h3>
95
+ <pre style="font-family: monospace"></pre>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ <div style="margin-top: 50px">
100
+ Check out the code for this page
101
+ <a
102
+ href="https://github.com/ColonelParrot/jscanify/blob/master/docs/tester.html"
103
+ target="_blank"
104
+ >here.</a
105
+ >
106
+ </div>
107
+ </div>
108
+
109
+ <script src="https://docs.opencv.org/4.7.0/opencv.js" async></script>
110
+ <!-- warning: loading OpenCV can take some time. Load asynchronously -->
111
+ <script src="https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@master/src/jscanify.min.js"></script>
112
+ <script>
113
+ window.addEventListener("load", function () {
114
+ const scanner = new jscanify();
115
+ fileInput.addEventListener("change", function (e) {
116
+ if (e.target.files.length) {
117
+ const image = e.target.files[0];
118
+ orig.src = URL.createObjectURL(image);
119
+ clearData();
120
+ result.style.display = "block";
121
+
122
+ orig.onload = function () {
123
+ const highlightedCanvas = scanner.highlightPaper(orig);
124
+ highlighted.appendChild(highlightedCanvas);
125
+
126
+ const extractedCanvas = scanner.extractPaper(orig, 772, 1000);
127
+ extracted.appendChild(extractedCanvas);
128
+
129
+ const contour = scanner.findPaperContour(cv.imread(orig));
130
+ const cornerPoints = scanner.getCornerPoints(contour);
131
+ cornerPts.querySelector("pre").textContent = JSON.stringify(
132
+ cornerPoints,
133
+ null,
134
+ 4
135
+ );
136
+ };
137
+ }
138
+ });
139
+ });
140
+
141
+ function clearData() {
142
+ highlighted.querySelector("canvas")?.remove();
143
+ extracted.querySelector("canvas")?.remove();
144
+ cornerPts.querySelector("pre").textContent = "";
145
+ }
146
+ </script>
147
+ </body>
148
+ </html>
package/package.json CHANGED
@@ -1,32 +1,32 @@
1
- {
2
- "name": "jscanify",
3
- "version": "1.1.0",
4
- "description": "Open-source Javascript mobile document scanner.",
5
- "main": "src/jscanify-node.js",
6
- "directories": {
7
- "doc": "docs"
8
- },
9
- "scripts": {
10
- "test": "mocha"
11
- },
12
- "repository": {
13
- "type": "git",
14
- "url": "https://github.com/ColonelParrot/jscanify.git"
15
- },
16
- "keywords": [
17
- "js",
18
- "scanner",
19
- "document-scanner"
20
- ],
21
- "author": "ColonelParrot",
22
- "license": "MIT",
23
- "bugs": {
24
- "url": "https://github.com/ColonelParrot/jscanify/issues"
25
- },
26
- "homepage": "https://colonelparrot.github.io/jscanify/",
27
- "dependencies": {
28
- "canvas": "^2.11.2",
29
- "jsdom": "^22.0.0",
30
- "mocha": "^10.2.0"
31
- }
32
- }
1
+ {
2
+ "name": "jscanify",
3
+ "version": "1.3.0",
4
+ "description": "Open-source Javascript mobile document scanner.",
5
+ "main": "src/jscanify-node.js",
6
+ "directories": {
7
+ "doc": "docs"
8
+ },
9
+ "scripts": {
10
+ "test": "mocha --trace-uncaught"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/puffinsoft/jscanify.git"
15
+ },
16
+ "keywords": [
17
+ "js",
18
+ "scanner",
19
+ "document-scanner"
20
+ ],
21
+ "author": "ColonelParrot",
22
+ "license": "MIT",
23
+ "bugs": {
24
+ "url": "https://github.com/puffinsoft/jscanify/issues"
25
+ },
26
+ "homepage": "https://colonelparrot.github.io/jscanify/",
27
+ "dependencies": {
28
+ "canvas": "^2.11.2",
29
+ "jsdom": "^22.0.0",
30
+ "mocha": "^10.2.0"
31
+ }
32
+ }
@@ -1,4 +1,4 @@
1
- /*! jscanify v1.1.0 | (c) ColonelParrot and other contributors | MIT License */
1
+ /*! jscanify v1.3.0 | (c) ColonelParrot and other contributors | MIT License */
2
2
 
3
3
  const { Canvas, createCanvas, Image, ImageData } = require("canvas");
4
4
  const { JSDOM } = require("jsdom");
@@ -22,7 +22,7 @@ let cv;
22
22
  * @returns distance between two points
23
23
  */
24
24
  function distance(p1, p2) {
25
- return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
25
+ return Math.hypot(p1.x - p2.x, p1.y - p2.y);
26
26
  }
27
27
 
28
28
  class jscanify {
@@ -44,7 +44,7 @@ class jscanify {
44
44
  */
45
45
  findPaperContour(img) {
46
46
  const imgGray = new cv.Mat();
47
- cv.cvtColor(img, imgGray, cv.COLOR_RGBA2GRAY);
47
+ cv.Canny(img, imgGray, 50, 200);
48
48
 
49
49
  const imgBlur = new cv.Mat();
50
50
  cv.GaussianBlur(
@@ -69,6 +69,7 @@ class jscanify {
69
69
  cv.RETR_CCOMP,
70
70
  cv.CHAIN_APPROX_SIMPLE
71
71
  );
72
+
72
73
  let maxArea = 0;
73
74
  let maxContourIndex = -1;
74
75
  for (let i = 0; i < contours.size(); ++i) {
@@ -140,10 +141,10 @@ class jscanify {
140
141
  * @param {*} image image to process
141
142
  * @param {*} resultWidth desired result paper width
142
143
  * @param {*} resultHeight desired result paper height
143
- * @param {*} onComplete callback with `HTMLCanvasElement` passed - the unwarped paper
144
144
  * @param {*} cornerPoints optional custom corner points, in case automatic corner points are incorrect
145
+ * @returns `HTMLCanvasElement` containing undistorted image
145
146
  */
146
- extractPaper(image, resultWidth, resultHeight, onComplete, cornerPoints) {
147
+ extractPaper(image, resultWidth, resultHeight, cornerPoints) {
147
148
  const canvas = createCanvas();
148
149
  const img = cv.imread(image);
149
150
  const maxContour = this.findPaperContour(img);
@@ -187,15 +188,10 @@ class jscanify {
187
188
  );
188
189
 
189
190
  cv.imshow(canvas, warpedDst);
190
- const canvasContext = canvas.getContext("2d");
191
- canvasContext.save();
192
- canvasContext.scale(1, -1);
193
- canvasContext.drawImage(canvas, 0, -resultHeight);
194
- canvasContext.restore();
195
191
 
196
192
  img.delete();
197
193
  warpedDst.delete();
198
- onComplete(canvas);
194
+ return canvas;
199
195
  }
200
196
 
201
197
  /**
@@ -222,25 +218,25 @@ class jscanify {
222
218
  for (let i = 0; i < contour.data32S.length; i += 2) {
223
219
  const point = { x: contour.data32S[i], y: contour.data32S[i + 1] };
224
220
  const dist = distance(point, center);
225
- if (point.x < center.x && point.y > center.y) {
221
+ if (point.x < center.x && point.y < center.y) {
226
222
  // top left
227
223
  if (dist > topLeftCornerDist) {
228
224
  topLeftCorner = point;
229
225
  topLeftCornerDist = dist;
230
226
  }
231
- } else if (point.x > center.x && point.y > center.y) {
227
+ } else if (point.x > center.x && point.y < center.y) {
232
228
  // top right
233
229
  if (dist > topRightCornerDist) {
234
230
  topRightCorner = point;
235
231
  topRightCornerDist = dist;
236
232
  }
237
- } else if (point.x < center.x && point.y < center.y) {
233
+ } else if (point.x < center.x && point.y > center.y) {
238
234
  // bottom left
239
235
  if (dist > bottomLeftCornerDist) {
240
236
  bottomLeftCorner = point;
241
237
  bottomLeftCornerDist = dist;
242
238
  }
243
- } else if (point.x > center.x && point.y < center.y) {
239
+ } else if (point.x > center.x && point.y > center.y) {
244
240
  // bottom right
245
241
  if (dist > bottomRightCornerDist) {
246
242
  bottomRightCorner = point;