react-native-rectangle-doc-scanner 0.19.0 → 0.20.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/dist/DocScanner.js +29 -15
- package/dist/utils/overlay.js +6 -0
- package/package.json +1 -1
- package/src/DocScanner.tsx +32 -18
- package/src/utils/overlay.tsx +7 -0
package/dist/DocScanner.js
CHANGED
|
@@ -43,26 +43,40 @@ const react_native_fast_opencv_1 = require("react-native-fast-opencv");
|
|
|
43
43
|
const overlay_1 = require("./utils/overlay");
|
|
44
44
|
const stability_1 = require("./utils/stability");
|
|
45
45
|
const isConvexQuadrilateral = (points) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
let previous = 0;
|
|
50
|
-
for (let i = 0; i < 4; i++) {
|
|
51
|
-
const p0 = points[i];
|
|
52
|
-
const p1 = points[(i + 1) % 4];
|
|
53
|
-
const p2 = points[(i + 2) % 4];
|
|
54
|
-
const cross = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x);
|
|
55
|
-
if (Math.abs(cross) < 1e-3) {
|
|
46
|
+
'worklet';
|
|
47
|
+
try {
|
|
48
|
+
if (points.length !== 4) {
|
|
56
49
|
return false;
|
|
57
50
|
}
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
// Validate all points have valid x and y
|
|
52
|
+
for (const p of points) {
|
|
53
|
+
if (typeof p.x !== 'number' || typeof p.y !== 'number' ||
|
|
54
|
+
!isFinite(p.x) || !isFinite(p.y)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
60
57
|
}
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
let previous = 0;
|
|
59
|
+
for (let i = 0; i < 4; i++) {
|
|
60
|
+
const p0 = points[i];
|
|
61
|
+
const p1 = points[(i + 1) % 4];
|
|
62
|
+
const p2 = points[(i + 2) % 4];
|
|
63
|
+
const cross = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x);
|
|
64
|
+
// Relax the collinearity check - allow very small cross products
|
|
65
|
+
if (Math.abs(cross) < 0.1) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (i === 0) {
|
|
69
|
+
previous = cross;
|
|
70
|
+
}
|
|
71
|
+
else if (previous * cross < 0) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
63
74
|
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return false;
|
|
64
79
|
}
|
|
65
|
-
return true;
|
|
66
80
|
};
|
|
67
81
|
const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, minStableFrames = 8, cameraProps, children, }) => {
|
|
68
82
|
const device = (0, react_native_vision_camera_1.useCameraDevice)('back');
|
package/dist/utils/overlay.js
CHANGED
|
@@ -39,8 +39,14 @@ const react_native_skia_1 = require("@shopify/react-native-skia");
|
|
|
39
39
|
const Overlay = ({ quad, color = '#e7a649' }) => {
|
|
40
40
|
const path = (0, react_1.useMemo)(() => {
|
|
41
41
|
if (!quad) {
|
|
42
|
+
if (__DEV__) {
|
|
43
|
+
console.log('[Overlay] no quad');
|
|
44
|
+
}
|
|
42
45
|
return null;
|
|
43
46
|
}
|
|
47
|
+
if (__DEV__) {
|
|
48
|
+
console.log('[Overlay] drawing quad:', quad);
|
|
49
|
+
}
|
|
44
50
|
const skPath = react_native_skia_1.Skia.Path.Make();
|
|
45
51
|
skPath.moveTo(quad[0].x, quad[0].y);
|
|
46
52
|
quad.slice(1).forEach((p) => skPath.lineTo(p.x, p.y));
|
package/package.json
CHANGED
package/src/DocScanner.tsx
CHANGED
|
@@ -17,30 +17,44 @@ import { checkStability } from './utils/stability';
|
|
|
17
17
|
import type { Point } from './types';
|
|
18
18
|
|
|
19
19
|
const isConvexQuadrilateral = (points: Point[]) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
'worklet';
|
|
21
|
+
try {
|
|
22
|
+
if (points.length !== 4) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
// Validate all points have valid x and y
|
|
27
|
+
for (const p of points) {
|
|
28
|
+
if (typeof p.x !== 'number' || typeof p.y !== 'number' ||
|
|
29
|
+
!isFinite(p.x) || !isFinite(p.y)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
const p0 = points[i];
|
|
28
|
-
const p1 = points[(i + 1) % 4];
|
|
29
|
-
const p2 = points[(i + 2) % 4];
|
|
30
|
-
const cross = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x);
|
|
34
|
+
let previous = 0;
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
for (let i = 0; i < 4; i++) {
|
|
37
|
+
const p0 = points[i];
|
|
38
|
+
const p1 = points[(i + 1) % 4];
|
|
39
|
+
const p2 = points[(i + 2) % 4];
|
|
40
|
+
const cross = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x);
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
// Relax the collinearity check - allow very small cross products
|
|
43
|
+
if (Math.abs(cross) < 0.1) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (i === 0) {
|
|
48
|
+
previous = cross;
|
|
49
|
+
} else if (previous * cross < 0) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
40
52
|
}
|
|
41
|
-
}
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
return true;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
44
58
|
};
|
|
45
59
|
|
|
46
60
|
type CameraRef = {
|
package/src/utils/overlay.tsx
CHANGED
|
@@ -10,9 +10,16 @@ type OverlayProps = {
|
|
|
10
10
|
export const Overlay: React.FC<OverlayProps> = ({ quad, color = '#e7a649' }) => {
|
|
11
11
|
const path = useMemo(() => {
|
|
12
12
|
if (!quad) {
|
|
13
|
+
if (__DEV__) {
|
|
14
|
+
console.log('[Overlay] no quad');
|
|
15
|
+
}
|
|
13
16
|
return null;
|
|
14
17
|
}
|
|
15
18
|
|
|
19
|
+
if (__DEV__) {
|
|
20
|
+
console.log('[Overlay] drawing quad:', quad);
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
const skPath = Skia.Path.Make();
|
|
17
24
|
skPath.moveTo(quad[0].x, quad[0].y);
|
|
18
25
|
quad.slice(1).forEach((p) => skPath.lineTo(p.x, p.y));
|