jscanify 1.3.4 → 1.4.1
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 +1 -1
- package/docs/index.html +1 -1
- package/package.json +1 -1
- package/src/jscanify-node.js +3 -3
- package/src/jscanify.js +3 -3
- package/test/tests.js +100 -97
- /package/docs/images/test/{test4.jpg → test4.JPG} +0 -0
- /package/docs/images/test/{test5.jpg → test5.JPG} +0 -0
- /package/docs/images/test/{test6.jpg → test6.JPG} +0 -0
- /package/docs/images/test/{test7.jpg → test7.JPG} +0 -0
- /package/docs/images/test/{test8.jpg → test8.JPG} +0 -0
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ Available on <a href="https://www.npmjs.com/package/jscanify">npm</a> or via <a
|
|
|
28
28
|
- paper scanning with distortion correction
|
|
29
29
|
|
|
30
30
|
> [!IMPORTANT]
|
|
31
|
-
> 🎉 _jscanify v1.3.
|
|
31
|
+
> 🎉 _jscanify v1.3.0+_ has just been released! **Same API, better results.** See the [release](https://github.com/puffinsoft/jscanify/releases/tag/v1.3.0) to see the difference! 🎉
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
- 🆕 glare suppression
|
package/docs/index.html
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
fill="black" class="octo-body"></path>
|
|
33
33
|
</svg>
|
|
34
34
|
</a>
|
|
35
|
-
<img src="images/logo-full.png" alt="jscanify logo" style="
|
|
35
|
+
<img src="images/logo-full.png" alt="jscanify logo" style="width: 375px" />
|
|
36
36
|
<h2>the javascript document scanning library.</h2>
|
|
37
37
|
<br />
|
|
38
38
|
<div class="view-on">
|
package/package.json
CHANGED
package/src/jscanify-node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! jscanify v1.
|
|
1
|
+
/*! jscanify v1.4.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");
|
|
@@ -153,9 +153,9 @@ class jscanify {
|
|
|
153
153
|
extractPaper(image, resultWidth, resultHeight, cornerPoints) {
|
|
154
154
|
const canvas = createCanvas();
|
|
155
155
|
const img = cv.imread(image);
|
|
156
|
-
const maxContour = this.findPaperContour(img);
|
|
156
|
+
const maxContour = cornerPoints ? null : this.findPaperContour(img);
|
|
157
157
|
|
|
158
|
-
if(maxContour == null){
|
|
158
|
+
if(maxContour == null && cornerPoints === undefined){
|
|
159
159
|
return null;
|
|
160
160
|
}
|
|
161
161
|
|
package/src/jscanify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! jscanify v1.
|
|
1
|
+
/*! jscanify v1.4.0 | (c) ColonelParrot and other contributors | MIT License */
|
|
2
2
|
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === "object" && typeof module !== "undefined"
|
|
@@ -144,9 +144,9 @@
|
|
|
144
144
|
extractPaper(image, resultWidth, resultHeight, cornerPoints) {
|
|
145
145
|
const canvas = document.createElement("canvas");
|
|
146
146
|
const img = cv.imread(image);
|
|
147
|
-
const maxContour = this.findPaperContour(img);
|
|
147
|
+
const maxContour = cornerPoints ? null : this.findPaperContour(img);
|
|
148
148
|
|
|
149
|
-
if(maxContour == null){
|
|
149
|
+
if(maxContour == null && cornerPoints === undefined){
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
152
|
|
package/test/tests.js
CHANGED
|
@@ -16,122 +16,125 @@ const path = require("path");
|
|
|
16
16
|
const OUTPUT_FOLDER = __dirname.replaceAll("\\", "/") + "/output/";
|
|
17
17
|
|
|
18
18
|
const TEST_IMAGE_DIRECTORY = path.join(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
__dirname,
|
|
20
|
+
"..",
|
|
21
|
+
"docs",
|
|
22
|
+
"images",
|
|
23
|
+
"test"
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* delete previously generated output images
|
|
28
28
|
*/
|
|
29
29
|
function setup() {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
console.log("=== setting up tests ===");
|
|
31
|
+
console.log("Deleting previously generated images");
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
if (!existsSync(OUTPUT_FOLDER)) {
|
|
34
|
+
mkdirSync(OUTPUT_FOLDER);
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
readdirSync(OUTPUT_FOLDER).forEach((file) => {
|
|
38
|
+
unlinkSync(path.join(OUTPUT_FOLDER, file));
|
|
39
|
+
})
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
let scanner;
|
|
43
|
+
let cv;
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
before(function (done) {
|
|
46
|
+
console.log("=== beginning tests ===");
|
|
47
|
+
console.log("loading OpenCV.js...");
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
scanner = new jscanify();
|
|
50
|
+
scanner.loadOpenCV(function (loadedCv) {
|
|
51
|
+
cv = loadedCv;
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
function test(testImage, imageCount) {
|
|
55
|
-
describe("image #" + imageCount, function () {
|
|
56
|
-
it("should highlight paper", function (done) {
|
|
57
|
-
const highlighted = scanner.highlightPaper(testImage);
|
|
58
|
-
const higlightedOutputPath = OUTPUT_FOLDER + "highlighted-" + imageCount + ".jpg";
|
|
59
|
-
writeFileSync(
|
|
60
|
-
higlightedOutputPath,
|
|
61
|
-
highlighted.toBuffer("image/jpeg")
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
assert.ok(existsSync(higlightedOutputPath));
|
|
65
|
-
done();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("should extract paper", function (done) {
|
|
69
|
-
const extracted = scanner.extractPaper(testImage, 386, 500);
|
|
70
|
-
const extractedOutputPath = OUTPUT_FOLDER + "extracted-" + imageCount + ".jpg";
|
|
71
|
-
|
|
72
|
-
writeFileSync(
|
|
73
|
-
extractedOutputPath,
|
|
74
|
-
extracted.toBuffer("image/jpeg")
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
assert.ok(existsSync(extractedOutputPath));
|
|
53
|
+
console.log("Finished loading OpenCV.js");
|
|
54
|
+
console.log("Writing test images to: " + OUTPUT_FOLDER);
|
|
55
|
+
setup()
|
|
78
56
|
done();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{ p: topLeftCorner, text: "top left corner" },
|
|
97
|
-
{ p: topRightCorner, text: "top right corner" },
|
|
98
|
-
{ p: bottomLeftCorner, text: "bottom left corner" },
|
|
99
|
-
{ p: bottomRightCorner, text: "bottom right corner" },
|
|
100
|
-
];
|
|
101
|
-
ctx.fillStyle = "cyan";
|
|
102
|
-
ctx.font = "25px serif";
|
|
103
|
-
points.forEach(({ p: point, text }) => {
|
|
104
|
-
ctx.beginPath();
|
|
105
|
-
ctx.arc(point.x, point.y, 15, 0, 2 * Math.PI, false);
|
|
106
|
-
ctx.fillText(text, point.x + 30, point.y)
|
|
107
|
-
ctx.fill();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* tests an individual image
|
|
62
|
+
*/
|
|
63
|
+
function test(testImage, imageCount) {
|
|
64
|
+
describe("image #" + imageCount, function () {
|
|
65
|
+
it("should highlight paper", function () {
|
|
66
|
+
const highlighted = scanner.highlightPaper(testImage);
|
|
67
|
+
const higlightedOutputPath = OUTPUT_FOLDER + "highlighted-" + imageCount + ".jpg";
|
|
68
|
+
writeFileSync(
|
|
69
|
+
higlightedOutputPath,
|
|
70
|
+
highlighted.toBuffer("image/jpeg")
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
assert.ok(existsSync(higlightedOutputPath));
|
|
108
74
|
});
|
|
109
75
|
|
|
110
|
-
|
|
111
|
-
|
|
76
|
+
it("should extract paper", function () {
|
|
77
|
+
const extracted = scanner.extractPaper(testImage, 386, 500);
|
|
78
|
+
const extractedOutputPath = OUTPUT_FOLDER + "extracted-" + imageCount + ".jpg";
|
|
112
79
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
80
|
+
writeFileSync(
|
|
81
|
+
extractedOutputPath,
|
|
82
|
+
extracted.toBuffer("image/jpeg")
|
|
83
|
+
);
|
|
118
84
|
|
|
119
|
-
|
|
85
|
+
assert.ok(existsSync(extractedOutputPath));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should label corner points", function () {
|
|
89
|
+
const parsedImage = cv.imread(testImage);
|
|
90
|
+
const paperContour = scanner.findPaperContour(parsedImage);
|
|
91
|
+
const {
|
|
92
|
+
topLeftCorner,
|
|
93
|
+
topRightCorner,
|
|
94
|
+
bottomLeftCorner,
|
|
95
|
+
bottomRightCorner,
|
|
96
|
+
} = scanner.getCornerPoints(paperContour, testImage);
|
|
97
|
+
|
|
98
|
+
const canvas = createCanvas();
|
|
99
|
+
|
|
100
|
+
cv.imshow(canvas, parsedImage);
|
|
101
|
+
const ctx = canvas.getContext("2d");
|
|
102
|
+
const points = [
|
|
103
|
+
{ p: topLeftCorner, text: "top left corner" },
|
|
104
|
+
{ p: topRightCorner, text: "top right corner" },
|
|
105
|
+
{ p: bottomLeftCorner, text: "bottom left corner" },
|
|
106
|
+
{ p: bottomRightCorner, text: "bottom right corner" },
|
|
107
|
+
];
|
|
108
|
+
ctx.fillStyle = "cyan";
|
|
109
|
+
ctx.font = "25px serif";
|
|
110
|
+
points.forEach(({ p: point, text }) => {
|
|
111
|
+
ctx.beginPath();
|
|
112
|
+
ctx.arc(point.x, point.y, 15, 0, 2 * Math.PI, false);
|
|
113
|
+
ctx.fillText(text, point.x + 30, point.y)
|
|
114
|
+
ctx.fill();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const cornerPointsOutputPath = OUTPUT_FOLDER + "corner_points-" + imageCount + ".jpg";
|
|
118
|
+
writeFileSync(cornerPointsOutputPath, canvas.toBuffer("image/jpeg"));
|
|
119
|
+
|
|
120
|
+
assert.ok(existsSync(cornerPointsOutputPath));
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
120
124
|
|
|
121
|
-
|
|
125
|
+
let imageCount = 1;
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
/*
|
|
128
|
+
* go through all images in test image directory
|
|
129
|
+
*/
|
|
130
|
+
readdirSync(TEST_IMAGE_DIRECTORY).forEach((file) => {
|
|
127
131
|
const TEST_IMAGE_PATH = path.join(TEST_IMAGE_DIRECTORY, file);
|
|
128
|
-
|
|
129
|
-
if(!file.endsWith("-sized.png")){ // these images are for the website, not testing
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
|
|
133
|
+
if (!file.endsWith("-sized.png")) { // these images are for the website, not testing
|
|
134
|
+
let tempCount = imageCount++;
|
|
135
|
+
|
|
136
|
+
loadImage(TEST_IMAGE_PATH).then(function (image) {
|
|
137
|
+
test(image, tempCount);
|
|
138
|
+
});
|
|
135
139
|
}
|
|
136
|
-
|
|
137
|
-
});
|
|
140
|
+
})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|