react-native-rectangle-doc-scanner 1.13.0 → 1.14.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.
@@ -1,178 +0,0 @@
1
- # Native Module Architecture Plan
2
-
3
- This document lays out the roadmap for migrating the library from its current
4
- VisionCamera/OpenCV implementation to a fully native document scanner module
5
- that mirrors the behaviour of `react-native-document-scanner-plugin` while
6
- keeping support for custom React components and overlays.
7
-
8
- ## Goals
9
-
10
- - Expose a `<DocScanner />` React view component that renders a native camera
11
- preview.
12
- - Maintain the ability to layer custom React children (buttons, hints, headers)
13
- on top of the preview.
14
- - Provide the detected polygon and stability information every frame, so the
15
- existing Skia overlay and auto-capture logic continue working.
16
- - Support both automatic and manual capture flows; captures should resolve with
17
- both cropped and original image metadata.
18
- - Keep the public TypeScript API as close as possible to the current version to
19
- minimise breaking changes for consuming apps.
20
-
21
- ## High-Level Architecture
22
-
23
- ```
24
- ┌──────────────────────────────────────────────────────────────────────┐
25
- │ React Native (TypeScript) │
26
- │ ┌────────────────────────────┐ events / commands ┌─────────────┐ │
27
- │ │ DocScanner.tsx (wrapper) ├───────────────────────▶│ Native View │ │
28
- │ │ - Manages refs │◀───────────────────────┤ Module │ │
29
- │ │ - Handles props │ layout callbacks └─────────────┘ │
30
- │ │ - Renders Overlay + UI │ │
31
- │ └────────────────────────────┘ │
32
- │ ▲ ▲ │
33
- │ │onRectangleDetect │onPictureTaken │
34
- └────────────────┴─────────────────────────────┴───────────────────────┘
35
- │ │
36
- ┌────────┴────────┐ ┌──────┴──────┐
37
- │ iOS (Swift) │ │ Android │
38
- │ DocScannerView │ │ DocScannerView │
39
- │ - AVCapture │ │ - CameraX │
40
- │ - Vision / VNDetectRectangles │ │ - ML Kit / OpenCV│
41
- │ - VNDocumentCamera for capture ││ - On-device cropping │
42
- └──────────────────┘ └───────────────────────┘
43
- ```
44
-
45
- ### React Native Layer
46
-
47
- - `DocScanner.tsx`
48
- - Forwards props to the native view via `requireNativeComponent`.
49
- - Holds a ref to call `capture()`, `setTorchEnabled()`, etc.
50
- - Converts native events into the existing `Point[]` / stability format.
51
- - Continues rendering the Skia-based `Overlay` and any child components.
52
- - `index.ts`
53
- - Exports the wrapper and new types.
54
- - TypeScript definitions for native events, capture result, and imperative
55
- methods (`DocScannerHandle`).
56
-
57
- ### iOS Implementation
58
-
59
- - Create `ios/DocScannerView.swift`
60
- - Subclass of `UIView` hosting an `AVCaptureVideoPreviewLayer`.
61
- - Uses `AVCaptureSession` with `AVCaptureVideoDataOutput` to stream frames.
62
- - Runs `VNDetectRectanglesRequest` on a background queue for polygon
63
- detection.
64
- - Emits `onRectangleDetect` events (containing points, stability counter, and
65
- frame size) via `RCTDirectEventBlock`.
66
- - Implements `capture()` by calling `AVCapturePhotoOutput` and optionally
67
- running `CIFilter` warps for perspective correction.
68
- - Saves both original and cropped images, returning their URIs plus width /
69
- height.
70
-
71
- - Create `ios/DocScannerViewManager.m`
72
- - Registers the component as `RNRDocScannerView` (name to be decided).
73
- - Exposes props: `overlayColor`, `detectionCountBeforeCapture`, `torchEnabled`,
74
- `useBase64`, `quality`, etc.
75
- - Exposes commands / methods: `capture`, `setTorchEnabled`, `reset`.
76
-
77
- - Create backing Swift files:
78
- - `DocScannerFrameProcessor.swift` – handles rectangle detection and stability
79
- scoring.
80
- - `DocScannerCaptureCoordinator.swift` – manages photo output, perspective
81
- correction, optional VisionKit integration.
82
- - `DocScannerEventPayload.swift` – strongly typed event payloads.
83
-
84
- ### Android Implementation
85
-
86
- - Create `android/src/main/java/.../DocScannerView.kt`
87
- - Extends `FrameLayout`, hosts a `PreviewView` from CameraX.
88
- - Sets up `ProcessCameraProvider` with `ImageAnalysis` for frame processing.
89
- - Runs ML Kit Document Scanner API (or OpenCV fallback) to detect quads.
90
- - Emits events through `@ReactProp` + `UIManagerModule` event dispatch.
91
- - Maintains stability counter similar to current JS implementation.
92
-
93
- - Create `DocScannerViewManager.kt`
94
- - Registers the view name (e.g. `RNRDocScannerView`).
95
- - Maps props (`overlayColor`, `detectionCountBeforeCapture`, etc.).
96
- - Implements `receiveCommand` to handle `capture`, `torch`, `reset`.
97
-
98
- - Create `DocScannerModule.kt`
99
- - Exposes imperative methods if needed for non-view functionality (e.g. file
100
- cleanup).
101
-
102
- - Provide utility classes:
103
- - `ImageCropper.kt` – applies perspective transformations using OpenCV or
104
- RenderScript.
105
- - `PathUtils.kt` – file management for temporary images.
106
- - `RectangleEvent.kt` – serialisable event payload.
107
-
108
- ### Event Contract
109
-
110
- `onRectangleDetect` event shape (identical for iOS & Android):
111
-
112
- ```ts
113
- type RectangleEventPayload = {
114
- rectangleCoordinates: {
115
- topLeft: Point;
116
- topRight: Point;
117
- bottomRight: Point;
118
- bottomLeft: Point;
119
- } | null;
120
- stableCounter: number;
121
- frameWidth: number;
122
- frameHeight: number;
123
- };
124
- ```
125
-
126
- `onPictureTaken` event shape:
127
-
128
- ```ts
129
- type PictureEvent = {
130
- croppedImage: string | null; // file:// or base64 depending on props
131
- initialImage: string;
132
- width: number;
133
- height: number;
134
- };
135
- ```
136
-
137
- ### Props Mapping
138
-
139
- | Prop | Description | Native handling |
140
- |-------------------------------|-----------------------------------------------------|---------------------------------------|
141
- | `overlayColor` | Stroke colour for overlay (forwarded to events) | Only metadata – actual overlay is JS |
142
- | `detectionCountBeforeCapture`| Minimum stable frames before auto capture | Native stability counter |
143
- | `autoCapture` | If `true`, native triggers capture automatically | Native triggers `capture()` internally|
144
- | `enableTorch` | Controls device torch | Maps to `AVCaptureDevice` / CameraX |
145
- | `quality` | JPEG quality (0–100) | Controls compression in native capture|
146
- | `useBase64` | If `true`, return base64 strings instead of files | Native encode |
147
- | `showGrid`, `gridColor`... | Handled in JS overlay; no native changes required | N/A |
148
-
149
- ### Migration Steps
150
-
151
- 1. **Scaffold native module directories**
152
- - Add `ios/` and `android/` folders with minimal React Native module wiring.
153
-
154
- 2. **Implement iOS detection & capture**
155
- - Set up camera session, rectangle detection, event dispatch.
156
- - Support auto capture and manual capture commands.
157
-
158
- 3. **Implement Android detection & capture**
159
- - Mirror iOS logic with CameraX + ML Kit/OpenCV.
160
-
161
- 4. **Update TypeScript wrapper**
162
- - Replace VisionCamera/OpenCV logic with `requireNativeComponent`.
163
- - Keep existing overlay and UI contract intact.
164
-
165
- 5. **Testing & validation**
166
- - Write example app update (outside this package) to verify events, overlay,
167
- auto-capture.
168
- - Ensure TypeScript typings align with native behaviour.
169
-
170
- 6. **Documentation**
171
- - Update README with new installation instructions (pods/gradle changes,
172
- permissions, peer deps).
173
- - Document new props & events, auto/manual capture behaviour.
174
-
175
- This plan focuses on creating a native module while preserving the custom
176
- overlay UX. Each platform will require significant native code, but the above
177
- structure provides the blueprint for implementation.
178
-
@@ -1,49 +0,0 @@
1
- import Foundation
2
- import React
3
-
4
- @objc(RNRDocScannerModule)
5
- class RNRDocScannerModule: NSObject, RCTBridgeModule {
6
- static func moduleName() -> String! {
7
- "RNRDocScannerModule"
8
- }
9
-
10
- static func requiresMainQueueSetup() -> Bool {
11
- true
12
- }
13
-
14
- @objc var bridge: RCTBridge?
15
-
16
- @objc func capture(_ reactTag: NSNumber, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
17
- bridge?.uiManager?.addUIBlock { _, viewRegistry in
18
- guard let view = viewRegistry?[reactTag] as? RNRDocScannerView else {
19
- reject(RNRDocScannerError.viewNotFound.code, RNRDocScannerError.viewNotFound.message, nil)
20
- return
21
- }
22
-
23
- view.capture { result in
24
- switch result {
25
- case let .success(payload):
26
- resolve([
27
- "croppedImage": payload.croppedImage as Any,
28
- "initialImage": payload.originalImage,
29
- "width": payload.width,
30
- "height": payload.height,
31
- ])
32
- case let .failure(error as RNRDocScannerError):
33
- reject(error.code, error.message, error)
34
- case let .failure(error):
35
- reject("capture_failed", error.localizedDescription, error)
36
- }
37
- }
38
- }
39
- }
40
-
41
- @objc func reset(_ reactTag: NSNumber) {
42
- bridge?.uiManager?.addUIBlock { _, viewRegistry in
43
- guard let view = viewRegistry?[reactTag] as? RNRDocScannerView else {
44
- return
45
- }
46
- view.resetStability()
47
- }
48
- }
49
- }