react-native-rectangle-doc-scanner 3.31.0 → 3.33.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/CropEditor.js +2 -5
- package/dist/DocScanner.js +7 -2
- package/dist/FullDocScanner.js +7 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/utils/coordinate.d.ts +1 -0
- package/dist/utils/coordinate.js +8 -1
- package/package.json +1 -1
- package/src/CropEditor.tsx +3 -7
- package/src/DocScanner.tsx +10 -5
- package/src/FullDocScanner.tsx +8 -13
- package/src/index.ts +1 -0
- package/src/utils/coordinate.ts +7 -0
package/dist/CropEditor.js
CHANGED
|
@@ -92,11 +92,8 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
|
|
|
92
92
|
? document.rectangle
|
|
93
93
|
: document.quad && document.quad.length === 4
|
|
94
94
|
? (0, coordinate_1.quadToRectangle)(document.quad)
|
|
95
|
-
:
|
|
96
|
-
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
const scaled = (0, coordinate_1.scaleRectangle)(sourceRectangle, baseWidth, baseHeight, imageSize.width, imageSize.height);
|
|
95
|
+
: (0, coordinate_1.createFullImageRectangle)(baseWidth, baseHeight);
|
|
96
|
+
const scaled = (0, coordinate_1.scaleRectangle)(sourceRectangle ?? (0, coordinate_1.createFullImageRectangle)(baseWidth, baseHeight), baseWidth, baseHeight, imageSize.width, imageSize.height);
|
|
100
97
|
return scaled;
|
|
101
98
|
}, [document.rectangle, document.quad, document.width, document.height, imageSize]);
|
|
102
99
|
const handleImageLoad = (0, react_1.useCallback)((event) => {
|
package/dist/DocScanner.js
CHANGED
|
@@ -140,7 +140,12 @@ exports.DocScanner = (0, react_1.forwardRef)(({ onCapture, overlayColor = DEFAUL
|
|
|
140
140
|
return Promise.reject(error);
|
|
141
141
|
}
|
|
142
142
|
if (result && typeof result.then === 'function') {
|
|
143
|
-
return result
|
|
143
|
+
return result
|
|
144
|
+
.then((payload) => {
|
|
145
|
+
handlePictureTaken(payload);
|
|
146
|
+
return payload;
|
|
147
|
+
})
|
|
148
|
+
.catch((error) => {
|
|
144
149
|
captureOriginRef.current = 'auto';
|
|
145
150
|
throw error;
|
|
146
151
|
});
|
|
@@ -157,7 +162,7 @@ exports.DocScanner = (0, react_1.forwardRef)(({ onCapture, overlayColor = DEFAUL
|
|
|
157
162
|
},
|
|
158
163
|
};
|
|
159
164
|
});
|
|
160
|
-
}, []);
|
|
165
|
+
}, [handlePictureTaken]);
|
|
161
166
|
const handleManualCapture = (0, react_1.useCallback)(() => {
|
|
162
167
|
captureOriginRef.current = 'manual';
|
|
163
168
|
capture().catch((error) => {
|
package/dist/FullDocScanner.js
CHANGED
|
@@ -41,12 +41,6 @@ const CropEditor_1 = require("./CropEditor");
|
|
|
41
41
|
const coordinate_1 = require("./utils/coordinate");
|
|
42
42
|
const stripFileUri = (value) => value.replace(/^file:\/\//, '');
|
|
43
43
|
const ensureFileUri = (value) => (value.startsWith('file://') ? value : `file://${value}`);
|
|
44
|
-
const createFullImageRectangle = (width, height) => ({
|
|
45
|
-
topLeft: { x: 0, y: 0 },
|
|
46
|
-
topRight: { x: width, y: 0 },
|
|
47
|
-
bottomRight: { x: width, y: height },
|
|
48
|
-
bottomLeft: { x: 0, y: height },
|
|
49
|
-
});
|
|
50
44
|
const resolveImageSize = (path, fallbackWidth, fallbackHeight) => new Promise((resolve) => {
|
|
51
45
|
react_native_1.Image.getSize(ensureFileUri(path), (width, height) => resolve({ width, height }), () => resolve({
|
|
52
46
|
width: fallbackWidth > 0 ? fallbackWidth : 0,
|
|
@@ -54,9 +48,10 @@ const resolveImageSize = (path, fallbackWidth, fallbackHeight) => new Promise((r
|
|
|
54
48
|
}));
|
|
55
49
|
});
|
|
56
50
|
const normalizeCapturedDocument = (document) => {
|
|
51
|
+
const { origin: _origin, ...rest } = document;
|
|
57
52
|
const normalizedPath = stripFileUri(document.initialPath ?? document.path);
|
|
58
53
|
return {
|
|
59
|
-
...
|
|
54
|
+
...rest,
|
|
60
55
|
path: normalizedPath,
|
|
61
56
|
initialPath: document.initialPath ? stripFileUri(document.initialPath) : normalizedPath,
|
|
62
57
|
croppedPath: document.croppedPath ? stripFileUri(document.croppedPath) : null,
|
|
@@ -104,10 +99,8 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
104
99
|
initialRectangle = (0, coordinate_1.scaleRectangle)(quadRectangle, baseWidth, baseHeight, imageSize.width, imageSize.height);
|
|
105
100
|
}
|
|
106
101
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
setCropRectangle(initialRectangle);
|
|
110
|
-
}
|
|
102
|
+
cropInitializedRef.current = true;
|
|
103
|
+
setCropRectangle(initialRectangle ?? (0, coordinate_1.createFullImageRectangle)(imageSize.width || 1, imageSize.height || 1));
|
|
111
104
|
}, [capturedDoc, imageSize]);
|
|
112
105
|
const resetState = (0, react_1.useCallback)(() => {
|
|
113
106
|
setScreen('scanner');
|
|
@@ -150,7 +143,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
150
143
|
const scaledRectangle = rectangleBase
|
|
151
144
|
? (0, coordinate_1.scaleRectangle)(rectangleBase, baseWidth || targetWidth, baseHeight || targetHeight, targetWidth, targetHeight)
|
|
152
145
|
: null;
|
|
153
|
-
const rectangleToUse = scaledRectangle ?? createFullImageRectangle(targetWidth, targetHeight);
|
|
146
|
+
const rectangleToUse = scaledRectangle ?? (0, coordinate_1.createFullImageRectangle)(targetWidth, targetHeight);
|
|
154
147
|
const base64 = await new Promise((resolve, reject) => {
|
|
155
148
|
cropManager.crop({
|
|
156
149
|
topLeft: rectangleToUse.topLeft,
|
|
@@ -247,7 +240,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
247
240
|
fallbackRectangle = (0, coordinate_1.scaleRectangle)(quadRectangle, baseWidth || targetWidth, baseHeight || targetHeight, targetWidth, targetHeight);
|
|
248
241
|
}
|
|
249
242
|
}
|
|
250
|
-
const rectangleToUse = cropRectangle ?? fallbackRectangle ?? createFullImageRectangle(targetWidth, targetHeight);
|
|
243
|
+
const rectangleToUse = cropRectangle ?? fallbackRectangle ?? (0, coordinate_1.createFullImageRectangle)(targetWidth, targetHeight);
|
|
251
244
|
const base64 = await new Promise((resolve, reject) => {
|
|
252
245
|
cropManager.crop({
|
|
253
246
|
topLeft: rectangleToUse.topLeft,
|
|
@@ -299,7 +292,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
299
292
|
}, [onClose, resetState]);
|
|
300
293
|
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
301
294
|
screen === 'scanner' && (react_1.default.createElement(react_native_1.View, { style: styles.flex },
|
|
302
|
-
react_1.default.createElement(DocScanner_1.DocScanner, { ref: docScannerRef, autoCapture: !manualCapture, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture },
|
|
295
|
+
react_1.default.createElement(DocScanner_1.DocScanner, { ref: docScannerRef, autoCapture: !manualCapture, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture, showManualCaptureButton: true },
|
|
303
296
|
react_1.default.createElement(react_native_1.View, { style: styles.overlay, pointerEvents: "box-none" },
|
|
304
297
|
react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.closeButton, onPress: handleClose, accessibilityLabel: mergedStrings.cancel, accessibilityRole: "button" },
|
|
305
298
|
react_1.default.createElement(react_native_1.Text, { style: styles.closeButtonLabel }, "\u00D7")),
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export { FullDocScanner } from './FullDocScanner';
|
|
|
4
4
|
export type { FullDocScannerResult, FullDocScannerProps, FullDocScannerStrings, } from './FullDocScanner';
|
|
5
5
|
export type { Point, Quad, Rectangle, CapturedDocument } from './types';
|
|
6
6
|
export type { DetectionConfig, DocScannerHandle, DocScannerCapture, RectangleDetectEvent, } from './DocScanner';
|
|
7
|
-
export { quadToRectangle, rectangleToQuad, scaleCoordinates, scaleRectangle, } from './utils/coordinate';
|
|
7
|
+
export { quadToRectangle, rectangleToQuad, scaleCoordinates, scaleRectangle, createFullImageRectangle, } from './utils/coordinate';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.scaleRectangle = exports.scaleCoordinates = exports.rectangleToQuad = exports.quadToRectangle = exports.FullDocScanner = exports.CropEditor = exports.DocScanner = void 0;
|
|
3
|
+
exports.createFullImageRectangle = exports.scaleRectangle = exports.scaleCoordinates = exports.rectangleToQuad = exports.quadToRectangle = exports.FullDocScanner = exports.CropEditor = exports.DocScanner = void 0;
|
|
4
4
|
// Main components
|
|
5
5
|
var DocScanner_1 = require("./DocScanner");
|
|
6
6
|
Object.defineProperty(exports, "DocScanner", { enumerable: true, get: function () { return DocScanner_1.DocScanner; } });
|
|
@@ -14,3 +14,4 @@ Object.defineProperty(exports, "quadToRectangle", { enumerable: true, get: funct
|
|
|
14
14
|
Object.defineProperty(exports, "rectangleToQuad", { enumerable: true, get: function () { return coordinate_1.rectangleToQuad; } });
|
|
15
15
|
Object.defineProperty(exports, "scaleCoordinates", { enumerable: true, get: function () { return coordinate_1.scaleCoordinates; } });
|
|
16
16
|
Object.defineProperty(exports, "scaleRectangle", { enumerable: true, get: function () { return coordinate_1.scaleRectangle; } });
|
|
17
|
+
Object.defineProperty(exports, "createFullImageRectangle", { enumerable: true, get: function () { return coordinate_1.createFullImageRectangle; } });
|
|
@@ -8,6 +8,7 @@ export declare const quadToRectangle: (quad: Point[]) => Rectangle | null;
|
|
|
8
8
|
* Convert Rectangle format back to quad points array
|
|
9
9
|
*/
|
|
10
10
|
export declare const rectangleToQuad: (rect: Rectangle) => Point[];
|
|
11
|
+
export declare const createFullImageRectangle: (width: number, height: number) => Rectangle;
|
|
11
12
|
/**
|
|
12
13
|
* Scale coordinates from one dimension to another
|
|
13
14
|
* Useful when image dimensions differ from display dimensions
|
package/dist/utils/coordinate.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.scaleRectangle = exports.scaleCoordinates = exports.rectangleToQuad = exports.quadToRectangle = void 0;
|
|
3
|
+
exports.scaleRectangle = exports.scaleCoordinates = exports.createFullImageRectangle = exports.rectangleToQuad = exports.quadToRectangle = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Convert quad points array to Rectangle format for perspective cropper
|
|
6
6
|
* Assumes quad points are ordered: [topLeft, topRight, bottomRight, bottomLeft]
|
|
@@ -29,6 +29,13 @@ const rectangleToQuad = (rect) => {
|
|
|
29
29
|
];
|
|
30
30
|
};
|
|
31
31
|
exports.rectangleToQuad = rectangleToQuad;
|
|
32
|
+
const createFullImageRectangle = (width, height) => ({
|
|
33
|
+
topLeft: { x: 0, y: 0 },
|
|
34
|
+
topRight: { x: width, y: 0 },
|
|
35
|
+
bottomRight: { x: width, y: height },
|
|
36
|
+
bottomLeft: { x: 0, y: height },
|
|
37
|
+
});
|
|
38
|
+
exports.createFullImageRectangle = createFullImageRectangle;
|
|
32
39
|
/**
|
|
33
40
|
* Scale coordinates from one dimension to another
|
|
34
41
|
* Useful when image dimensions differ from display dimensions
|
package/package.json
CHANGED
package/src/CropEditor.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { View, StyleSheet, Image, Dimensions, ActivityIndicator, Text } from 're
|
|
|
3
3
|
import CustomImageCropper from 'react-native-perspective-image-cropper';
|
|
4
4
|
import type { Rectangle as CropperRectangle } from 'react-native-perspective-image-cropper';
|
|
5
5
|
import type { Point, Rectangle, CapturedDocument } from './types';
|
|
6
|
-
import { quadToRectangle, scaleRectangle } from './utils/coordinate';
|
|
6
|
+
import { createFullImageRectangle, quadToRectangle, scaleRectangle } from './utils/coordinate';
|
|
7
7
|
|
|
8
8
|
interface CropEditorProps {
|
|
9
9
|
document: CapturedDocument;
|
|
@@ -81,14 +81,10 @@ export const CropEditor: React.FC<CropEditorProps> = ({
|
|
|
81
81
|
? document.rectangle
|
|
82
82
|
: document.quad && document.quad.length === 4
|
|
83
83
|
? quadToRectangle(document.quad)
|
|
84
|
-
:
|
|
85
|
-
|
|
86
|
-
if (!sourceRectangle) {
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
84
|
+
: createFullImageRectangle(baseWidth, baseHeight);
|
|
89
85
|
|
|
90
86
|
const scaled = scaleRectangle(
|
|
91
|
-
sourceRectangle,
|
|
87
|
+
sourceRectangle ?? createFullImageRectangle(baseWidth, baseHeight),
|
|
92
88
|
baseWidth,
|
|
93
89
|
baseHeight,
|
|
94
90
|
imageSize.width,
|
package/src/DocScanner.tsx
CHANGED
|
@@ -212,10 +212,15 @@ export const DocScanner = forwardRef<DocScannerHandle, Props>(
|
|
|
212
212
|
return Promise.reject(error);
|
|
213
213
|
}
|
|
214
214
|
if (result && typeof result.then === 'function') {
|
|
215
|
-
return result
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
return result
|
|
216
|
+
.then((payload: PictureEvent) => {
|
|
217
|
+
handlePictureTaken(payload);
|
|
218
|
+
return payload;
|
|
219
|
+
})
|
|
220
|
+
.catch((error: unknown) => {
|
|
221
|
+
captureOriginRef.current = 'auto';
|
|
222
|
+
throw error;
|
|
223
|
+
});
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
return new Promise<PictureEvent>((resolve, reject) => {
|
|
@@ -230,7 +235,7 @@ export const DocScanner = forwardRef<DocScannerHandle, Props>(
|
|
|
230
235
|
},
|
|
231
236
|
};
|
|
232
237
|
});
|
|
233
|
-
}, []);
|
|
238
|
+
}, [handlePictureTaken]);
|
|
234
239
|
|
|
235
240
|
const handleManualCapture = useCallback(() => {
|
|
236
241
|
captureOriginRef.current = 'manual';
|
package/src/FullDocScanner.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import { DocScanner } from './DocScanner';
|
|
|
13
13
|
import { CropEditor } from './CropEditor';
|
|
14
14
|
import type { CapturedDocument, Point, Quad, Rectangle } from './types';
|
|
15
15
|
import type { DetectionConfig, DocScannerHandle, DocScannerCapture } from './DocScanner';
|
|
16
|
-
import { quadToRectangle, scaleRectangle } from './utils/coordinate';
|
|
16
|
+
import { createFullImageRectangle, quadToRectangle, scaleRectangle } from './utils/coordinate';
|
|
17
17
|
|
|
18
18
|
type CustomCropManagerType = {
|
|
19
19
|
crop: (
|
|
@@ -34,13 +34,6 @@ const stripFileUri = (value: string) => value.replace(/^file:\/\//, '');
|
|
|
34
34
|
|
|
35
35
|
const ensureFileUri = (value: string) => (value.startsWith('file://') ? value : `file://${value}`);
|
|
36
36
|
|
|
37
|
-
const createFullImageRectangle = (width: number, height: number): Rectangle => ({
|
|
38
|
-
topLeft: { x: 0, y: 0 },
|
|
39
|
-
topRight: { x: width, y: 0 },
|
|
40
|
-
bottomRight: { x: width, y: height },
|
|
41
|
-
bottomLeft: { x: 0, y: height },
|
|
42
|
-
});
|
|
43
|
-
|
|
44
37
|
const resolveImageSize = (
|
|
45
38
|
path: string,
|
|
46
39
|
fallbackWidth: number,
|
|
@@ -58,9 +51,10 @@ const resolveImageSize = (
|
|
|
58
51
|
});
|
|
59
52
|
|
|
60
53
|
const normalizeCapturedDocument = (document: DocScannerCapture): CapturedDocument => {
|
|
54
|
+
const { origin: _origin, ...rest } = document;
|
|
61
55
|
const normalizedPath = stripFileUri(document.initialPath ?? document.path);
|
|
62
56
|
return {
|
|
63
|
-
...
|
|
57
|
+
...rest,
|
|
64
58
|
path: normalizedPath,
|
|
65
59
|
initialPath: document.initialPath ? stripFileUri(document.initialPath) : normalizedPath,
|
|
66
60
|
croppedPath: document.croppedPath ? stripFileUri(document.croppedPath) : null,
|
|
@@ -184,10 +178,10 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
184
178
|
}
|
|
185
179
|
}
|
|
186
180
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
181
|
+
cropInitializedRef.current = true;
|
|
182
|
+
setCropRectangle(
|
|
183
|
+
initialRectangle ?? createFullImageRectangle(imageSize.width || 1, imageSize.height || 1),
|
|
184
|
+
);
|
|
191
185
|
}, [capturedDoc, imageSize]);
|
|
192
186
|
|
|
193
187
|
const resetState = useCallback(() => {
|
|
@@ -462,6 +456,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
462
456
|
minStableFrames={minStableFrames ?? 6}
|
|
463
457
|
detectionConfig={detectionConfig}
|
|
464
458
|
onCapture={handleCapture}
|
|
459
|
+
showManualCaptureButton
|
|
465
460
|
>
|
|
466
461
|
<View style={styles.overlay} pointerEvents="box-none">
|
|
467
462
|
<TouchableOpacity
|
package/src/index.ts
CHANGED
package/src/utils/coordinate.ts
CHANGED
|
@@ -29,6 +29,13 @@ export const rectangleToQuad = (rect: Rectangle): Point[] => {
|
|
|
29
29
|
];
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
export const createFullImageRectangle = (width: number, height: number): Rectangle => ({
|
|
33
|
+
topLeft: { x: 0, y: 0 },
|
|
34
|
+
topRight: { x: width, y: 0 },
|
|
35
|
+
bottomRight: { x: width, y: height },
|
|
36
|
+
bottomLeft: { x: 0, y: height },
|
|
37
|
+
});
|
|
38
|
+
|
|
32
39
|
/**
|
|
33
40
|
* Scale coordinates from one dimension to another
|
|
34
41
|
* Useful when image dimensions differ from display dimensions
|