jscanify 1.1.0 → 1.2.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/README.md CHANGED
@@ -3,6 +3,10 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
+ <a href="https://www.jsdelivr.com/package/gh/ColonelParrot/jscanify"><img src="https://data.jsdelivr.com/v1/package/gh/ColonelParrot/jscanify/badge"></a>
7
+ <a href="https://cdnjs.com/libraries/jscanify"><img src="https://img.shields.io/cdnjs/v/jscanify"></a>
8
+ <a href="https://npmjs.com/package/jscanify"><img src="https://badgen.net/npm/dw/jscanify"></a>
9
+ <br />
6
10
  <a href="https://github.com/ColonelParrot/jscanify/blob/master/LICENSE"><img src="https://img.shields.io/github/license/ColonelParrot/jscanify.svg"></a>
7
11
  <a href="https://GitHub.com/ColonelParrot/jscanify/releases/"><img src="https://img.shields.io/github/release/ColonelParrot/jscanify.svg"></a>
8
12
  <a href="https://npmjs.com/package/jscanify"><img src="https://badgen.net/npm/v/jscanify"></a>
@@ -22,8 +26,8 @@ Available on <a href="https://www.npmjs.com/package/jscanify">npm</a> or via <a
22
26
  - paper detection & highlighting
23
27
  - paper scanning with distortion correction
24
28
 
25
- | Image Highlighting | Scanned Result |
26
- | ------------------------------------------------- | ----------------------------------------------- |
29
+ | Image Highlighting | Scanned Result |
30
+ | -------------------------------------------- | ------------------------------------------ |
27
31
  | <img src="docs/images/highlight-paper1.png"> | <img src="docs/images/scanned-paper1.png"> |
28
32
  | <img src="docs/images/highlight-paper2.png"> | <img src="docs/images/scanned-paper2.png"> |
29
33
 
@@ -46,6 +50,8 @@ cdn:
46
50
  <script src="https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@master/src/jscanify.min.js"></script>
47
51
  ```
48
52
 
53
+ > **Note**: jscanify on NodeJS is slightly different. See [wiki: use on NodeJS](https://github.com/ColonelParrot/jscanify/wiki#use-on-nodejs).
54
+
49
55
  ### Highlight Paper in Image
50
56
 
51
57
  ```html
@@ -67,9 +73,8 @@ const scanner = new jscanify();
67
73
  const paperWidth = 500;
68
74
  const paperHeight = 1000;
69
75
  image.onload = function () {
70
- scanner.extractPaper(image, paperWidth, paperHeight, (resultCanvas) => {
71
- document.body.appendChild(resultCanvas);
72
- });
76
+ const resultCanvas = scanner.extractPaper(image, paperWidth, paperHeight);
77
+ document.body.appendChild(resultCanvas);
73
78
  };
74
79
  ```
75
80
 
@@ -78,9 +83,10 @@ image.onload = function () {
78
83
  The following code continuously reads from the user's camera and highlights the paper:
79
84
 
80
85
  ```html
81
- <video id="video"></video>
82
- <canvas id="canvas"></canvas> <!-- original video -->
83
- <canvas id="result"></canvas> <!-- highlighted video -->
86
+ <video id="video"></video> <canvas id="canvas"></canvas>
87
+ <!-- original video -->
88
+ <canvas id="result"></canvas>
89
+ <!-- highlighted video -->
84
90
  ```
85
91
 
86
92
  ```js
@@ -102,6 +108,8 @@ navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
102
108
  ```
103
109
 
104
110
  To export the paper to a PDF, see [here](https://stackoverflow.com/questions/23681325/convert-canvas-to-pdf)
111
+
105
112
  ### Notes
113
+
106
114
  - for optimal paper detection, the paper should be placed on a flat surface with a solid background color
107
- - we recommend wrapping your code using `jscanify` in a window `load` event listener to ensure OpenCV is loaded
115
+ - we recommend wrapping your code using `jscanify` in a window `load` event listener to ensure OpenCV is loaded
package/docs/index.html CHANGED
@@ -103,7 +103,7 @@ image.onload = function () {
103
103
  It's that easy! Come check out the <a href="https://github.com/ColonelParrot/jscanify/wiki"
104
104
  target="_blank">documentation</a>!
105
105
  </div>
106
- <script src="https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@latest/src/jscanify.min.js"></script>
106
+ <script src="../src/jscanify.js"></script>
107
107
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
108
108
  <script src="script.js"></script>
109
109
 
package/docs/script.js CHANGED
@@ -32,12 +32,11 @@ $('#demo-images .image-container').click(function () {
32
32
  newImg.src = imageSrc
33
33
 
34
34
  newImg.onload = function(){
35
- scanner.extractPaper(newImg, 386, 500, (resultCanvas) => {
36
- $('#demo-result').append(resultCanvas);
35
+ const resultCanvas = scanner.extractPaper(newImg, 386, 500);
36
+ $('#demo-result').append(resultCanvas);
37
37
 
38
- const highlightedCanvas = scanner.highlightPaper(newImg)
39
- $('#demo-result').append(highlightedCanvas);
40
- });
38
+ const highlightedCanvas = scanner.highlightPaper(newImg)
39
+ $('#demo-result').append(highlightedCanvas);
41
40
  }
42
41
  })
43
42
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jscanify",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Open-source Javascript mobile document scanner.",
5
5
  "main": "src/jscanify-node.js",
6
6
  "directories": {
@@ -1,4 +1,4 @@
1
- /*! jscanify v1.1.0 | (c) ColonelParrot and other contributors | MIT License */
1
+ /*! jscanify v1.2.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");
@@ -143,7 +143,7 @@ class jscanify {
143
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
145
  */
146
- extractPaper(image, resultWidth, resultHeight, onComplete, cornerPoints) {
146
+ extractPaper(image, resultWidth, resultHeight, cornerPoints) {
147
147
  const canvas = createCanvas();
148
148
  const img = cv.imread(image);
149
149
  const maxContour = this.findPaperContour(img);
@@ -187,15 +187,10 @@ class jscanify {
187
187
  );
188
188
 
189
189
  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
190
 
196
191
  img.delete();
197
192
  warpedDst.delete();
198
- onComplete(canvas);
193
+ return canvas;
199
194
  }
200
195
 
201
196
  /**
@@ -222,25 +217,25 @@ class jscanify {
222
217
  for (let i = 0; i < contour.data32S.length; i += 2) {
223
218
  const point = { x: contour.data32S[i], y: contour.data32S[i + 1] };
224
219
  const dist = distance(point, center);
225
- if (point.x < center.x && point.y > center.y) {
220
+ if (point.x < center.x && point.y < center.y) {
226
221
  // top left
227
222
  if (dist > topLeftCornerDist) {
228
223
  topLeftCorner = point;
229
224
  topLeftCornerDist = dist;
230
225
  }
231
- } else if (point.x > center.x && point.y > center.y) {
226
+ } else if (point.x > center.x && point.y < center.y) {
232
227
  // top right
233
228
  if (dist > topRightCornerDist) {
234
229
  topRightCorner = point;
235
230
  topRightCornerDist = dist;
236
231
  }
237
- } else if (point.x < center.x && point.y < center.y) {
232
+ } else if (point.x < center.x && point.y > center.y) {
238
233
  // bottom left
239
234
  if (dist > bottomLeftCornerDist) {
240
235
  bottomLeftCorner = point;
241
236
  bottomLeftCornerDist = dist;
242
237
  }
243
- } else if (point.x > center.x && point.y < center.y) {
238
+ } else if (point.x > center.x && point.y > center.y) {
244
239
  // bottom right
245
240
  if (dist > bottomRightCornerDist) {
246
241
  bottomRightCorner = point;
package/src/jscanify.js CHANGED
@@ -1,11 +1,11 @@
1
- /*! jscanify v1.1.0 | (c) ColonelParrot and other contributors | MIT License */
1
+ /*! jscanify v1.2.0 | (c) ColonelParrot and other contributors | MIT License */
2
2
 
3
3
  (function (global, factory) {
4
4
  typeof exports === "object" && typeof module !== "undefined"
5
5
  ? (module.exports = factory())
6
6
  : typeof define === "function" && define.amd
7
- ? define(factory)
8
- : (global.jscanify = factory());
7
+ ? define(factory)
8
+ : (global.jscanify = factory());
9
9
  })(this, function () {
10
10
  "use strict";
11
11
 
@@ -20,7 +20,7 @@
20
20
  }
21
21
 
22
22
  class jscanify {
23
- constructor() { }
23
+ constructor() {}
24
24
 
25
25
  /**
26
26
  * Finds the contour of the paper within the image
@@ -134,7 +134,7 @@
134
134
  * @param {*} onComplete callback with `HTMLCanvasElement` passed - the unwarped paper
135
135
  * @param {*} cornerPoints optional custom corner points, in case automatic corner points are incorrect
136
136
  */
137
- extractPaper(image, resultWidth, resultHeight, onComplete, cornerPoints) {
137
+ extractPaper(image, resultWidth, resultHeight, cornerPoints) {
138
138
  const canvas = document.createElement("canvas");
139
139
 
140
140
  const img = cv.imread(image);
@@ -185,33 +185,17 @@
185
185
 
186
186
  cv.imshow(canvas, warpedDst);
187
187
 
188
- const newImg = document.createElement("img");
189
- newImg.src = canvas.toDataURL();
190
- newImg.onload = function () {
191
- // flip unwarped image
192
-
193
- let ctx = canvas.getContext("2d");
194
- ctx.clearRect(0, 0, canvas.width, canvas.height);
195
- canvas.width = resultWidth;
196
- canvas.height = resultHeight;
197
- ctx.setTransform(1, 0, 0, -1, 0, canvas.height);
198
-
199
- ctx.drawImage(newImg, 0, 0);
200
-
201
- ctx.setTransform(1, 0, 0, 1, 0, 0);
202
-
203
- img.delete();
204
- warpedDst.delete();
205
- onComplete(canvas);
206
- };
188
+ img.delete()
189
+ warpedDst.delete()
190
+ return canvas;
207
191
  }
208
-
192
+
209
193
  /**
210
194
  * Calculates the corner points of a contour.
211
195
  * @param {*} contour contour from {@link findPaperContour}
212
196
  * @returns object with properties `topLeftCorner`, `topRightCorner`, `bottomLeftCorner`, `bottomRightCorner`, each with `x` and `y` property
213
197
  */
214
- getCornerPoints(contour) {
198
+ getCornerPoints(contour) {
215
199
  let rect = cv.minAreaRect(contour);
216
200
  const center = rect.center;
217
201
 
@@ -230,25 +214,25 @@
230
214
  for (let i = 0; i < contour.data32S.length; i += 2) {
231
215
  const point = { x: contour.data32S[i], y: contour.data32S[i + 1] };
232
216
  const dist = distance(point, center);
233
- if (point.x < center.x && point.y > center.y) {
217
+ if (point.x < center.x && point.y < center.y) {
234
218
  // top left
235
219
  if (dist > topLeftCornerDist) {
236
220
  topLeftCorner = point;
237
221
  topLeftCornerDist = dist;
238
222
  }
239
- } else if (point.x > center.x && point.y > center.y) {
223
+ } else if (point.x > center.x && point.y < center.y) {
240
224
  // top right
241
225
  if (dist > topRightCornerDist) {
242
226
  topRightCorner = point;
243
227
  topRightCornerDist = dist;
244
228
  }
245
- } else if (point.x < center.x && point.y < center.y) {
229
+ } else if (point.x < center.x && point.y > center.y) {
246
230
  // bottom left
247
231
  if (dist > bottomLeftCornerDist) {
248
232
  bottomLeftCorner = point;
249
233
  bottomLeftCornerDist = dist;
250
234
  }
251
- } else if (point.x > center.x && point.y < center.y) {
235
+ } else if (point.x > center.x && point.y > center.y) {
252
236
  // bottom right
253
237
  if (dist > bottomRightCornerDist) {
254
238
  bottomRightCorner = point;
@@ -264,8 +248,7 @@
264
248
  bottomRightCorner,
265
249
  };
266
250
  }
267
-
268
251
  }
269
252
 
270
253
  return jscanify;
271
- });
254
+ });
package/test/tests.js CHANGED
@@ -1,8 +1,12 @@
1
+ /*
2
+ run tests with: npm test
3
+ */
4
+
1
5
  console.log("RUNNING JSCANIFY TESTS");
2
6
  console.log("Warning: This may take a bit");
3
7
 
4
- const { Canvas, createCanvas, Image, ImageData, loadImage } = require("canvas");
5
- const { writeFileSync, unlinkSync, existsSync } = require("fs");
8
+ const { loadImage, createCanvas } = require("canvas");
9
+ const { mkdirSync, writeFileSync, unlinkSync, existsSync } = require("fs");
6
10
  const assert = require("assert");
7
11
 
8
12
  const jscanify = require("../src/jscanify-node");
@@ -11,8 +15,11 @@ const path = require("path");
11
15
  const outputPaths = {
12
16
  highlight: __dirname + "/output/highlighted.jpg",
13
17
  extracted: __dirname + "/output/extracted.jpg",
18
+ cornerPoints: __dirname + "/output/corner_points.jpg",
14
19
  };
15
20
 
21
+ const baseFolder = __dirname.replaceAll("\\", "/") + "/output/";
22
+
16
23
  const TEST_IMAGE_PATH = path.join(
17
24
  __dirname,
18
25
  "..",
@@ -30,6 +37,10 @@ function setup() {
30
37
  unlinkSync(path);
31
38
  }
32
39
  });
40
+
41
+ if (!existsSync(baseFolder)) {
42
+ mkdirSync(baseFolder);
43
+ }
33
44
  }
34
45
 
35
46
  function test() {
@@ -39,7 +50,8 @@ function test() {
39
50
  console.log("loading OpenCV.js...");
40
51
  scanner.loadOpenCV(function (cv) {
41
52
  console.log("Finished loading OpenCV.js");
42
- describe("feature tests", function (done) {
53
+ console.log("Writing test images to: " + baseFolder);
54
+ describe("feature tests", function () {
43
55
  it("should highlight paper", function (done) {
44
56
  const highlighted = scanner.highlightPaper(testImage);
45
57
  writeFileSync(
@@ -48,19 +60,53 @@ function test() {
48
60
  );
49
61
 
50
62
  assert.ok(existsSync(outputPaths.highlight));
51
- done()
63
+ done();
52
64
  });
53
65
 
54
66
  it("should extract paper", function (done) {
55
- scanner.extractPaper(testImage, 386, 500, function (extracted) {
56
- writeFileSync(
57
- outputPaths.extracted,
58
- extracted.toBuffer("image/jpeg")
59
- );
60
-
61
- assert.ok(existsSync(outputPaths.extracted));
62
- done();
67
+ const extracted = scanner.extractPaper(testImage, 386, 500);
68
+ writeFileSync(
69
+ outputPaths.extracted,
70
+ extracted.toBuffer("image/jpeg")
71
+ );
72
+
73
+ assert.ok(existsSync(outputPaths.extracted));
74
+ done();
75
+ });
76
+
77
+ it("should label corner points", function (done) {
78
+ const parsedImage = cv.imread(testImage);
79
+ const paperContour = scanner.findPaperContour(parsedImage);
80
+ const {
81
+ topLeftCorner,
82
+ topRightCorner,
83
+ bottomLeftCorner,
84
+ bottomRightCorner,
85
+ } = scanner.getCornerPoints(paperContour, testImage);
86
+
87
+ const canvas = createCanvas();
88
+
89
+ cv.imshow(canvas, parsedImage);
90
+ const ctx = canvas.getContext("2d");
91
+ const points = [
92
+ { p: topLeftCorner, text: "top left corner" },
93
+ { p: topRightCorner, text: "top right corner" },
94
+ { p: bottomLeftCorner, text: "bottom left corner" },
95
+ { p: bottomRightCorner, text: "bottom right corner" },
96
+ ];
97
+ ctx.fillStyle = "cyan";
98
+ ctx.font = "25px serif";
99
+ points.forEach(({ p: point, text }) => {
100
+ ctx.beginPath();
101
+ ctx.arc(point.x, point.y, 15, 0, 2 * Math.PI, false);
102
+ ctx.fillText(text, point.x + 30, point.y)
103
+ ctx.fill();
63
104
  });
105
+
106
+ writeFileSync(outputPaths.cornerPoints, canvas.toBuffer("image/jpeg"));
107
+
108
+ assert.ok(existsSync(outputPaths.cornerPoints));
109
+ done();
64
110
  });
65
111
  });
66
112
  });
package/install.md DELETED
@@ -1,5 +0,0 @@
1
- run
2
-
3
- ```
4
- npm run install_arm64
5
- ```