react-native-rectangle-doc-scanner 0.3.0 → 0.4.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.
@@ -42,6 +42,28 @@ const react_native_reanimated_1 = require("react-native-reanimated");
42
42
  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
+ const isConvexQuadrilateral = (points) => {
46
+ if (points.length !== 4) {
47
+ return false;
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) {
56
+ return false;
57
+ }
58
+ if (i === 0) {
59
+ previous = cross;
60
+ }
61
+ else if (previous * cross < 0) {
62
+ return false;
63
+ }
64
+ }
65
+ return true;
66
+ };
45
67
  const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, minStableFrames = 8, cameraProps, children, }) => {
46
68
  const device = (0, react_native_vision_camera_1.useCameraDevice)('back');
47
69
  const { hasPermission, requestPermission } = (0, react_native_vision_camera_1.useCameraPermission)();
@@ -87,13 +109,18 @@ const DocScanner = ({ onCapture, overlayColor = '#e7a649', autoCapture = true, m
87
109
  const approx = react_native_fast_opencv_1.OpenCV.createObject(react_native_fast_opencv_1.ObjectType.PointVector);
88
110
  react_native_fast_opencv_1.OpenCV.invoke('approxPolyDP', c, approx, 0.02 * peri, true);
89
111
  const size = react_native_fast_opencv_1.OpenCV.invokeWithOutParam('size', approx);
90
- const { value: convex } = react_native_fast_opencv_1.OpenCV.invoke('isContourConvex', approx);
91
- if (convex && size === 4 && area > maxArea) {
92
- const pts = [];
93
- for (let j = 0; j < 4; j++) {
94
- const p = react_native_fast_opencv_1.OpenCV.invoke('atPoint', approx, j, 0);
95
- pts.push({ x: p.x / ratio, y: p.y / ratio });
96
- }
112
+ if (size !== 4) {
113
+ continue;
114
+ }
115
+ const pts = [];
116
+ for (let j = 0; j < 4; j++) {
117
+ const p = react_native_fast_opencv_1.OpenCV.invoke('atPoint', approx, j, 0);
118
+ pts.push({ x: p.x / ratio, y: p.y / ratio });
119
+ }
120
+ if (!isConvexQuadrilateral(pts)) {
121
+ continue;
122
+ }
123
+ if (area > maxArea) {
97
124
  best = pts;
98
125
  maxArea = area;
99
126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {
@@ -16,6 +16,33 @@ import { Overlay } from './utils/overlay';
16
16
  import { checkStability } from './utils/stability';
17
17
  import type { Point } from './types';
18
18
 
19
+ const isConvexQuadrilateral = (points: Point[]) => {
20
+ if (points.length !== 4) {
21
+ return false;
22
+ }
23
+
24
+ let previous = 0;
25
+
26
+ for (let i = 0; i < 4; i++) {
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);
31
+
32
+ if (Math.abs(cross) < 1e-3) {
33
+ return false;
34
+ }
35
+
36
+ if (i === 0) {
37
+ previous = cross;
38
+ } else if (previous * cross < 0) {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ return true;
44
+ };
45
+
19
46
  type CameraRef = {
20
47
  takePhoto: (options: { qualityPrioritization: 'balanced' | 'quality' | 'speed' }) => Promise<{
21
48
  path: string;
@@ -98,14 +125,21 @@ export const DocScanner: React.FC<Props> = ({
98
125
  const approx = OpenCV.createObject(ObjectType.PointVector);
99
126
  OpenCV.invoke('approxPolyDP', c, approx, 0.02 * peri, true);
100
127
  const size = OpenCV.invokeWithOutParam('size', approx);
101
- const { value: convex } = OpenCV.invoke('isContourConvex', approx);
102
-
103
- if (convex && size === 4 && area > maxArea) {
104
- const pts: Point[] = [];
105
- for (let j = 0; j < 4; j++) {
106
- const p = OpenCV.invoke('atPoint', approx, j, 0);
107
- pts.push({ x: p.x / ratio, y: p.y / ratio });
108
- }
128
+ if (size !== 4) {
129
+ continue;
130
+ }
131
+
132
+ const pts: Point[] = [];
133
+ for (let j = 0; j < 4; j++) {
134
+ const p = OpenCV.invoke('atPoint', approx, j, 0);
135
+ pts.push({ x: p.x / ratio, y: p.y / ratio });
136
+ }
137
+
138
+ if (!isConvexQuadrilateral(pts)) {
139
+ continue;
140
+ }
141
+
142
+ if (area > maxArea) {
109
143
  best = pts;
110
144
  maxArea = area;
111
145
  }