@jaak.ai/stamps 2.0.0-beta.3 → 2.0.0-beta.4
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 +216 -215
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +1786 -1052
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/my-component/my-component.css +440 -110
- package/dist/collection/components/my-component/my-component.js +829 -1120
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/CameraService.js +453 -0
- package/dist/collection/services/CameraService.js.map +1 -0
- package/dist/collection/services/DetectionService.js +369 -0
- package/dist/collection/services/DetectionService.js.map +1 -0
- package/dist/collection/services/EventBusService.js +42 -0
- package/dist/collection/services/EventBusService.js.map +1 -0
- package/dist/collection/services/LoggerService.js +40 -0
- package/dist/collection/services/LoggerService.js.map +1 -0
- package/dist/collection/services/ServiceContainer.js +66 -0
- package/dist/collection/services/ServiceContainer.js.map +1 -0
- package/dist/collection/services/StateManagerService.js +109 -0
- package/dist/collection/services/StateManagerService.js.map +1 -0
- package/dist/collection/services/factories/DeviceStrategyFactory.js +16 -0
- package/dist/collection/services/factories/DeviceStrategyFactory.js.map +1 -0
- package/dist/collection/services/interfaces/ICameraService.js +2 -0
- package/dist/collection/services/interfaces/ICameraService.js.map +1 -0
- package/dist/collection/services/interfaces/IDetectionService.js +2 -0
- package/dist/collection/services/interfaces/IDetectionService.js.map +1 -0
- package/dist/collection/services/interfaces/IEventBus.js +2 -0
- package/dist/collection/services/interfaces/IEventBus.js.map +1 -0
- package/dist/collection/services/interfaces/ILogger.js +2 -0
- package/dist/collection/services/interfaces/ILogger.js.map +1 -0
- package/dist/collection/services/interfaces/IStateManager.js +2 -0
- package/dist/collection/services/interfaces/IStateManager.js.map +1 -0
- package/dist/collection/services/strategies/HighPerformanceDeviceStrategy.js +30 -0
- package/dist/collection/services/strategies/HighPerformanceDeviceStrategy.js.map +1 -0
- package/dist/collection/services/strategies/IDeviceStrategy.js +2 -0
- package/dist/collection/services/strategies/IDeviceStrategy.js.map +1 -0
- package/dist/collection/services/strategies/LowMemoryDeviceStrategy.js +30 -0
- package/dist/collection/services/strategies/LowMemoryDeviceStrategy.js.map +1 -0
- package/dist/collection/types/component-types.js +2 -0
- package/dist/collection/types/component-types.js.map +1 -0
- package/dist/components/jaak-stamps.js +1802 -1076
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +1 -1
- package/dist/esm/jaak-stamps.entry.js +1786 -1052
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-10ee2dab.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-10ee2dab.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +83 -108
- package/dist/types/components.d.ts +23 -9
- package/dist/types/services/CameraService.d.ts +46 -0
- package/dist/types/services/DetectionService.d.ts +35 -0
- package/dist/types/services/EventBusService.d.ts +9 -0
- package/dist/types/services/LoggerService.d.ts +12 -0
- package/dist/types/services/ServiceContainer.d.ts +27 -0
- package/dist/types/services/StateManagerService.d.ts +15 -0
- package/dist/types/services/factories/DeviceStrategyFactory.d.ts +4 -0
- package/dist/types/services/interfaces/ICameraService.d.ts +34 -0
- package/dist/types/services/interfaces/IDetectionService.d.ts +31 -0
- package/dist/types/services/interfaces/IEventBus.d.ts +16 -0
- package/dist/types/services/interfaces/ILogger.d.ts +8 -0
- package/dist/types/services/interfaces/IStateManager.d.ts +35 -0
- package/dist/types/services/strategies/HighPerformanceDeviceStrategy.d.ts +6 -0
- package/dist/types/services/strategies/IDeviceStrategy.d.ts +21 -0
- package/dist/types/services/strategies/LowMemoryDeviceStrategy.d.ts +6 -0
- package/dist/types/types/component-types.d.ts +36 -0
- package/package.json +3 -3
- package/dist/jaak-stamps-webcomponent/p-14eb13d8.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-14eb13d8.entry.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# Jaak Stamps - Document Detector Web Component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A web component for automatic detection and capture of identification documents using computer vision.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
7
|
+
- Real-time automatic document detection
|
|
8
|
+
- Visual guide for optimal document positioning
|
|
9
|
+
- Intelligent document classification to determine if back capture is required
|
|
10
|
+
- Adaptive capture - automatically detects if document requires back side
|
|
11
|
+
- Dual output for each side: full frame and cropped document
|
|
12
|
+
- Configurable cropping with customizable margin around document
|
|
13
|
+
- Programmatic API for complete process control
|
|
14
|
+
- Responsive and mobile device compatible
|
|
15
|
+
- Automatic optimization for better performance
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Installation
|
|
18
18
|
|
|
19
19
|
### NPM
|
|
20
20
|
```bash
|
|
@@ -31,7 +31,7 @@ yarn add @jaak.ai/stamps
|
|
|
31
31
|
<script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Basic Usage
|
|
35
35
|
|
|
36
36
|
### HTML Vanilla
|
|
37
37
|
|
|
@@ -43,25 +43,25 @@ yarn add @jaak.ai/stamps
|
|
|
43
43
|
<script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
|
|
44
44
|
</head>
|
|
45
45
|
<body>
|
|
46
|
-
<jaak-stamps id="detector" debug="false" mask-size="
|
|
46
|
+
<jaak-stamps id="detector" debug="false" mask-size="80" crop-margin="20" capture-delay="1000" use-document-classification="false"></jaak-stamps>
|
|
47
47
|
|
|
48
|
-
<button onclick="startCapture()">
|
|
49
|
-
<button onclick="stopCapture()">
|
|
50
|
-
<button onclick="resetCapture()">
|
|
48
|
+
<button onclick="startCapture()">Start Capture</button>
|
|
49
|
+
<button onclick="stopCapture()">Stop</button>
|
|
50
|
+
<button onclick="resetCapture()">Reset</button>
|
|
51
51
|
|
|
52
52
|
<script>
|
|
53
53
|
const detector = document.getElementById('detector');
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// Listen for capture completed event
|
|
56
56
|
detector.addEventListener('captureCompleted', (event) => {
|
|
57
|
-
console.log('
|
|
58
|
-
// event.detail
|
|
57
|
+
console.log('Capture completed:', event.detail);
|
|
58
|
+
// event.detail contains the captured images
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
//
|
|
61
|
+
// Listen for component ready event
|
|
62
62
|
detector.addEventListener('isReady', (event) => {
|
|
63
|
-
console.log('
|
|
64
|
-
// event.detail
|
|
63
|
+
console.log('Component ready:', event.detail);
|
|
64
|
+
// event.detail indicates if the component is ready (true/false)
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
function startCapture() {
|
|
@@ -76,21 +76,21 @@ yarn add @jaak.ai/stamps
|
|
|
76
76
|
detector.resetCapture();
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
//
|
|
79
|
+
// Preload model (optional - improves performance)
|
|
80
80
|
async function preloadModel() {
|
|
81
81
|
try {
|
|
82
82
|
const result = await detector.preloadModel();
|
|
83
|
-
console.log('
|
|
83
|
+
console.log('Model preloaded:', result);
|
|
84
84
|
} catch (error) {
|
|
85
|
-
console.error('Error
|
|
85
|
+
console.error('Error preloading:', error);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
//
|
|
89
|
+
// Get images after capture
|
|
90
90
|
async function getImages() {
|
|
91
91
|
try {
|
|
92
92
|
const images = await detector.getCapturedImages();
|
|
93
|
-
console.log('
|
|
93
|
+
console.log('Captured images:', images);
|
|
94
94
|
} catch (error) {
|
|
95
95
|
console.error('Error:', error.message);
|
|
96
96
|
}
|
|
@@ -102,18 +102,18 @@ yarn add @jaak.ai/stamps
|
|
|
102
102
|
|
|
103
103
|
### Angular
|
|
104
104
|
|
|
105
|
-
#### 1.
|
|
105
|
+
#### 1. Install the component
|
|
106
106
|
```bash
|
|
107
107
|
npm install @jaak.ai/stamps
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
#### 2.
|
|
110
|
+
#### 2. Configure the module (app.module.ts)
|
|
111
111
|
```typescript
|
|
112
112
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
113
113
|
import { BrowserModule } from '@angular/platform-browser';
|
|
114
114
|
import { AppComponent } from './app.component';
|
|
115
115
|
|
|
116
|
-
//
|
|
116
|
+
// Import the web component
|
|
117
117
|
import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js';
|
|
118
118
|
|
|
119
119
|
@NgModule({
|
|
@@ -121,12 +121,12 @@ import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.e
|
|
|
121
121
|
imports: [BrowserModule],
|
|
122
122
|
providers: [],
|
|
123
123
|
bootstrap: [AppComponent],
|
|
124
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA] //
|
|
124
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA] // Allow custom elements
|
|
125
125
|
})
|
|
126
126
|
export class AppModule { }
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
#### 3.
|
|
129
|
+
#### 3. Use in the component
|
|
130
130
|
```typescript
|
|
131
131
|
// app.component.ts
|
|
132
132
|
import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
|
|
@@ -135,31 +135,31 @@ import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
|
|
|
135
135
|
selector: 'app-root',
|
|
136
136
|
template: `
|
|
137
137
|
<div class="container">
|
|
138
|
-
<h1>Detector
|
|
138
|
+
<h1>Document Detector</h1>
|
|
139
139
|
|
|
140
140
|
<jaak-stamps
|
|
141
141
|
#detector
|
|
142
142
|
[debug]="false"
|
|
143
|
-
[maskSize]="
|
|
144
|
-
[cropMargin]="
|
|
143
|
+
[maskSize]="80"
|
|
144
|
+
[cropMargin]="20"
|
|
145
145
|
[useDocumentClassification]="false"
|
|
146
146
|
(captureCompleted)="onCaptureCompleted($event)"
|
|
147
147
|
(isReady)="onComponentReady($event)">
|
|
148
148
|
</jaak-stamps>
|
|
149
149
|
|
|
150
150
|
<div class="controls">
|
|
151
|
-
<button (click)="preloadModel()">
|
|
152
|
-
<button (click)="startCapture()">
|
|
153
|
-
<button (click)="stopCapture()">
|
|
154
|
-
<button (click)="resetCapture()">
|
|
155
|
-
<button (click)="getImages()" [disabled]="!isCompleted">
|
|
151
|
+
<button (click)="preloadModel()">Preload Model</button>
|
|
152
|
+
<button (click)="startCapture()">Start Capture</button>
|
|
153
|
+
<button (click)="stopCapture()">Stop</button>
|
|
154
|
+
<button (click)="resetCapture()">Reset</button>
|
|
155
|
+
<button (click)="getImages()" [disabled]="!isCompleted">Get Images</button>
|
|
156
156
|
</div>
|
|
157
157
|
|
|
158
158
|
<div *ngIf="capturedData" class="results">
|
|
159
|
-
<h3>
|
|
160
|
-
<p>Total
|
|
161
|
-
<img *ngIf="capturedData.front.cropped" [src]="capturedData.front.cropped" alt="
|
|
162
|
-
<img *ngIf="capturedData.back.cropped" [src]="capturedData.back.cropped" alt="
|
|
159
|
+
<h3>Captured Images:</h3>
|
|
160
|
+
<p>Total images: {{ capturedData.metadata.totalImages }}</p>
|
|
161
|
+
<img *ngIf="capturedData.front.cropped" [src]="capturedData.front.cropped" alt="Front">
|
|
162
|
+
<img *ngIf="capturedData.back.cropped" [src]="capturedData.back.cropped" alt="Back">
|
|
163
163
|
</div>
|
|
164
164
|
</div>
|
|
165
165
|
`,
|
|
@@ -177,15 +177,15 @@ export class AppComponent implements OnInit {
|
|
|
177
177
|
isCompleted = false;
|
|
178
178
|
|
|
179
179
|
ngOnInit() {
|
|
180
|
-
//
|
|
180
|
+
// The element is already available after the view
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
async preloadModel() {
|
|
184
184
|
try {
|
|
185
185
|
const result = await this.detectorRef.nativeElement.preloadModel();
|
|
186
|
-
console.log('
|
|
186
|
+
console.log('Model preloaded:', result);
|
|
187
187
|
} catch (error) {
|
|
188
|
-
console.error('Error
|
|
188
|
+
console.error('Error preloading model:', error);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
@@ -193,7 +193,7 @@ export class AppComponent implements OnInit {
|
|
|
193
193
|
try {
|
|
194
194
|
await this.detectorRef.nativeElement.startCapture();
|
|
195
195
|
} catch (error) {
|
|
196
|
-
console.error('Error
|
|
196
|
+
console.error('Error starting capture:', error);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -210,41 +210,41 @@ export class AppComponent implements OnInit {
|
|
|
210
210
|
async getImages() {
|
|
211
211
|
try {
|
|
212
212
|
const images = await this.detectorRef.nativeElement.getCapturedImages();
|
|
213
|
-
console.log('
|
|
213
|
+
console.log('Images obtained:', images);
|
|
214
214
|
} catch (error) {
|
|
215
|
-
console.error('Error
|
|
215
|
+
console.error('Error getting images:', error);
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
onCaptureCompleted(event: any) {
|
|
220
|
-
console.log('
|
|
220
|
+
console.log('Capture completed in Angular:', event.detail);
|
|
221
221
|
this.capturedData = event.detail;
|
|
222
222
|
this.isCompleted = true;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
onComponentReady(event: any) {
|
|
226
|
-
console.log('
|
|
227
|
-
//
|
|
226
|
+
console.log('Component ready in Angular:', event.detail);
|
|
227
|
+
// The component is ready to start detection
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
231
|
|
|
232
232
|
### React
|
|
233
233
|
|
|
234
|
-
#### 1.
|
|
234
|
+
#### 1. Install the component
|
|
235
235
|
```bash
|
|
236
236
|
npm install @jaak.ai/stamps
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
#### 2.
|
|
239
|
+
#### 2. Create wrapper component (optional but recommended)
|
|
240
240
|
```jsx
|
|
241
241
|
// JaakStampsWrapper.jsx
|
|
242
242
|
import React, { useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
|
|
243
243
|
|
|
244
|
-
//
|
|
244
|
+
// Import the web component
|
|
245
245
|
import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js';
|
|
246
246
|
|
|
247
|
-
const JaakStampsWrapper = forwardRef(({ debug = false, maskSize =
|
|
247
|
+
const JaakStampsWrapper = forwardRef(({ debug = false, maskSize = 80, cropMargin = 20, useDocumentClassification = false, onCaptureCompleted, onIsReady }, ref) => {
|
|
248
248
|
const elementRef = useRef(null);
|
|
249
249
|
|
|
250
250
|
useImperativeHandle(ref, () => ({
|
|
@@ -298,7 +298,7 @@ const JaakStampsWrapper = forwardRef(({ debug = false, maskSize = 90, cropMargin
|
|
|
298
298
|
export default JaakStampsWrapper;
|
|
299
299
|
```
|
|
300
300
|
|
|
301
|
-
#### 3.
|
|
301
|
+
#### 3. Use in your React application
|
|
302
302
|
```jsx
|
|
303
303
|
// App.jsx
|
|
304
304
|
import React, { useRef, useState } from 'react';
|
|
@@ -311,22 +311,22 @@ function App() {
|
|
|
311
311
|
const [status, setStatus] = useState(null);
|
|
312
312
|
|
|
313
313
|
const handleCaptureCompleted = (data) => {
|
|
314
|
-
console.log('
|
|
314
|
+
console.log('Capture completed:', data);
|
|
315
315
|
setCapturedData(data);
|
|
316
316
|
setIsCompleted(true);
|
|
317
317
|
};
|
|
318
318
|
|
|
319
319
|
const handleIsReady = (isReady) => {
|
|
320
|
-
console.log('
|
|
321
|
-
//
|
|
320
|
+
console.log('Component ready:', isReady);
|
|
321
|
+
// The component is ready to start detection
|
|
322
322
|
};
|
|
323
323
|
|
|
324
324
|
const preloadModel = async () => {
|
|
325
325
|
try {
|
|
326
326
|
const result = await detectorRef.current?.preloadModel();
|
|
327
|
-
console.log('
|
|
327
|
+
console.log('Model preloaded:', result);
|
|
328
328
|
} catch (error) {
|
|
329
|
-
console.error('Error
|
|
329
|
+
console.error('Error preloading model:', error);
|
|
330
330
|
}
|
|
331
331
|
};
|
|
332
332
|
|
|
@@ -334,7 +334,7 @@ function App() {
|
|
|
334
334
|
try {
|
|
335
335
|
await detectorRef.current?.startCapture();
|
|
336
336
|
} catch (error) {
|
|
337
|
-
console.error('Error
|
|
337
|
+
console.error('Error starting capture:', error);
|
|
338
338
|
}
|
|
339
339
|
};
|
|
340
340
|
|
|
@@ -351,9 +351,9 @@ function App() {
|
|
|
351
351
|
const getImages = async () => {
|
|
352
352
|
try {
|
|
353
353
|
const images = await detectorRef.current?.getCapturedImages();
|
|
354
|
-
console.log('
|
|
354
|
+
console.log('Images obtained:', images);
|
|
355
355
|
} catch (error) {
|
|
356
|
-
console.error('Error
|
|
356
|
+
console.error('Error getting images:', error);
|
|
357
357
|
}
|
|
358
358
|
};
|
|
359
359
|
|
|
@@ -365,52 +365,51 @@ function App() {
|
|
|
365
365
|
return (
|
|
366
366
|
<div className="App">
|
|
367
367
|
<header className="App-header">
|
|
368
|
-
<h1>Detector
|
|
368
|
+
<h1>Document Detector - React</h1>
|
|
369
369
|
|
|
370
370
|
<JaakStampsWrapper
|
|
371
371
|
ref={detectorRef}
|
|
372
372
|
debug={false}
|
|
373
|
-
maskSize={
|
|
374
|
-
cropMargin={
|
|
373
|
+
maskSize={80}
|
|
374
|
+
cropMargin={20}
|
|
375
375
|
useDocumentClassification={false}
|
|
376
376
|
onCaptureCompleted={handleCaptureCompleted}
|
|
377
377
|
onIsReady={handleIsReady}
|
|
378
378
|
/>
|
|
379
379
|
|
|
380
380
|
<div className="controls">
|
|
381
|
-
<button onClick={preloadModel}>
|
|
382
|
-
<button onClick={startCapture}>
|
|
383
|
-
<button onClick={stopCapture}>
|
|
384
|
-
<button onClick={resetCapture}>
|
|
381
|
+
<button onClick={preloadModel}>Preload Model</button>
|
|
382
|
+
<button onClick={startCapture}>Start Capture</button>
|
|
383
|
+
<button onClick={stopCapture}>Stop</button>
|
|
384
|
+
<button onClick={resetCapture}>Reset</button>
|
|
385
385
|
<button onClick={getImages} disabled={!isCompleted}>
|
|
386
|
-
|
|
386
|
+
Get Images
|
|
387
387
|
</button>
|
|
388
|
-
<button onClick={checkStatus}>
|
|
388
|
+
<button onClick={checkStatus}>Check Status</button>
|
|
389
389
|
</div>
|
|
390
390
|
|
|
391
391
|
{status && (
|
|
392
392
|
<div className="status">
|
|
393
|
-
<h3>
|
|
394
|
-
<p>Video
|
|
395
|
-
<p>
|
|
396
|
-
<p>
|
|
397
|
-
<p>
|
|
398
|
-
<p>Modelo precargado: {status.isModelPreloaded ? 'Sí' : 'No'}</p>
|
|
393
|
+
<h3>Current Status:</h3>
|
|
394
|
+
<p>Video active: {status.isVideoActive ? 'Yes' : 'No'}</p>
|
|
395
|
+
<p>Step: {status.captureStep}</p>
|
|
396
|
+
<p>Process completed: {status.isProcessCompleted ? 'Yes' : 'No'}</p>
|
|
397
|
+
<p>Model preloaded: {status.isModelPreloaded ? 'Yes' : 'No'}</p>
|
|
399
398
|
</div>
|
|
400
399
|
)}
|
|
401
400
|
|
|
402
401
|
{capturedData && (
|
|
403
402
|
<div className="results">
|
|
404
|
-
<h3>
|
|
405
|
-
<p>Total
|
|
403
|
+
<h3>Capture Results:</h3>
|
|
404
|
+
<p>Total images: {capturedData.metadata.totalImages}</p>
|
|
406
405
|
<p>Timestamp: {capturedData.timestamp}</p>
|
|
407
406
|
|
|
408
407
|
{capturedData.front.cropped && (
|
|
409
408
|
<div>
|
|
410
|
-
<h4>
|
|
409
|
+
<h4>Document Front:</h4>
|
|
411
410
|
<img
|
|
412
411
|
src={capturedData.front.cropped}
|
|
413
|
-
alt="
|
|
412
|
+
alt="Document front"
|
|
414
413
|
style={{ maxWidth: '300px', border: '1px solid #ccc', margin: '10px' }}
|
|
415
414
|
/>
|
|
416
415
|
</div>
|
|
@@ -418,10 +417,10 @@ function App() {
|
|
|
418
417
|
|
|
419
418
|
{capturedData.back.cropped && (
|
|
420
419
|
<div>
|
|
421
|
-
<h4>
|
|
420
|
+
<h4>Document Back:</h4>
|
|
422
421
|
<img
|
|
423
422
|
src={capturedData.back.cropped}
|
|
424
|
-
alt="
|
|
423
|
+
alt="Document back"
|
|
425
424
|
style={{ maxWidth: '300px', border: '1px solid #ccc', margin: '10px' }}
|
|
426
425
|
/>
|
|
427
426
|
</div>
|
|
@@ -438,173 +437,175 @@ export default App;
|
|
|
438
437
|
|
|
439
438
|
## API Reference
|
|
440
439
|
|
|
441
|
-
###
|
|
440
|
+
### Properties/Attributes
|
|
442
441
|
|
|
443
|
-
|
|
|
444
|
-
|
|
445
|
-
| `debug` | `boolean` | `false` |
|
|
446
|
-
| `alignmentTolerance` | `number` | `
|
|
447
|
-
| `maskSize` | `number` | `
|
|
448
|
-
| `cropMargin` | `number` | `
|
|
449
|
-
| `
|
|
450
|
-
| `
|
|
442
|
+
| Property | Type | Default | Description |
|
|
443
|
+
|----------|------|---------|-------------|
|
|
444
|
+
| `debug` | `boolean` | `false` | Enables debug mode to show debugging information |
|
|
445
|
+
| `alignmentTolerance` | `number` | `15` | Tolerance in pixels to consider a side aligned |
|
|
446
|
+
| `maskSize` | `number` | `80` | Percentage of video that the detection mask will occupy (50-100) |
|
|
447
|
+
| `cropMargin` | `number` | `20` | Margin in pixels added to the document crop (0-100) |
|
|
448
|
+
| `captureDelay` | `number` | `1500` | Time in milliseconds the document must remain in position before automatically capturing (0-10000) |
|
|
449
|
+
| `useDocumentClassification` | `boolean` | `false` | Enables automatic document classification to determine if back capture is required. Only loads the classification model when enabled. |
|
|
450
|
+
| `preferredCamera` | `'auto' \| 'front' \| 'back'` | `'auto'` | Defines which camera to use: `'auto'` (automatic based on device), `'front'` (front camera), `'back'` (back camera) |
|
|
451
451
|
|
|
452
|
-
###
|
|
452
|
+
### Public Methods
|
|
453
453
|
|
|
454
|
-
|
|
|
454
|
+
| Method | Returns | Description |
|
|
455
455
|
|--------|---------|-------------|
|
|
456
|
-
| `startCapture()` | `Promise<void>` |
|
|
457
|
-
| `stopCapture()` | `Promise<void>` |
|
|
458
|
-
| `resetCapture()` | `Promise<void>` |
|
|
459
|
-
| `preloadModel()` | `Promise<{success: boolean, message?: string, error?: string}>` |
|
|
460
|
-
| `getCapturedImages()` | `Promise<CapturedImages>` |
|
|
461
|
-
| `isProcessCompleted()` | `Promise<boolean>` |
|
|
462
|
-
| `getStatus()` | `Promise<Status>` |
|
|
463
|
-
| `skipBackCapture()` | `Promise<void>` |
|
|
464
|
-
| `getCameraInfo()` | `Promise<CameraInfo>` |
|
|
465
|
-
| `setPreferredCamera(camera)` | `Promise<{success: boolean, selectedCamera: string, availableCameras: number}>` |
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
456
|
+
| `startCapture()` | `Promise<void>` | Starts the detection and capture process |
|
|
457
|
+
| `stopCapture()` | `Promise<void>` | Stops the process and releases the camera |
|
|
458
|
+
| `resetCapture()` | `Promise<void>` | Resets the capture process |
|
|
459
|
+
| `preloadModel()` | `Promise<{success: boolean, message?: string, error?: string}>` | Preloads the detection model |
|
|
460
|
+
| `getCapturedImages()` | `Promise<CapturedImages>` | Gets the captured images (only after completion) |
|
|
461
|
+
| `isProcessCompleted()` | `Promise<boolean>` | Checks if the process has been completed |
|
|
462
|
+
| `getStatus()` | `Promise<Status>` | Gets the current detector status |
|
|
463
|
+
| `skipBackCapture()` | `Promise<void>` | Skips back capture (only available in 'back' step) |
|
|
464
|
+
| `getCameraInfo()` | `Promise<CameraInfo>` | Gets detailed information about available cameras |
|
|
465
|
+
| `setPreferredCamera(camera)` | `Promise<{success: boolean, selectedCamera: string, availableCameras: number}>` | Sets the preferred camera ('auto', 'front', 'back') |
|
|
466
|
+
| `setCaptureDelay(delay)` | `Promise<{success: boolean, captureDelay: number}>` | Sets the wait time before automatically capturing (0-10000ms) |
|
|
467
|
+
| `getCaptureDelay()` | `Promise<number>` | Gets the current wait time configured for automatic capture |
|
|
468
|
+
| `setTorchEnabled(enabled)` | `Promise<{success: boolean, enabled: boolean}>` | Enables or disables the camera torch/flash |
|
|
469
|
+
| `focusAtPoint(x, y)` | `Promise<{success: boolean, coordinates: {x: number, y: number}}>` | Focuses the camera at specific coordinates |
|
|
470
|
+
|
|
471
|
+
### Events
|
|
472
|
+
|
|
473
|
+
| Event | Payload | Description |
|
|
474
|
+
|-------|---------|-------------|
|
|
475
|
+
| `captureCompleted` | `CapturedImages` | Emitted when the capture process is completed |
|
|
476
|
+
| `isReady` | `boolean` | Emitted when the component is ready to start detection (models loaded) |
|
|
477
|
+
|
|
478
|
+
### Data Types
|
|
475
479
|
|
|
476
480
|
```typescript
|
|
477
481
|
interface CapturedImages {
|
|
478
482
|
front: {
|
|
479
|
-
fullFrame: string | null; // Base64
|
|
480
|
-
cropped: string | null; // Base64
|
|
483
|
+
fullFrame: string | null; // Base64 of the complete front image
|
|
484
|
+
cropped: string | null; // Base64 of the cropped front document
|
|
481
485
|
};
|
|
482
486
|
back: {
|
|
483
|
-
fullFrame: string | null; // Base64
|
|
484
|
-
cropped: string | null; // Base64
|
|
487
|
+
fullFrame: string | null; // Base64 of the complete back image
|
|
488
|
+
cropped: string | null; // Base64 of the cropped back document
|
|
485
489
|
};
|
|
486
|
-
timestamp: string; // ISO timestamp
|
|
490
|
+
timestamp: string; // ISO timestamp of capture
|
|
487
491
|
metadata: {
|
|
488
|
-
totalImages: number; //
|
|
489
|
-
processCompleted: boolean; //
|
|
490
|
-
backCaptureSkipped?: boolean; //
|
|
492
|
+
totalImages: number; // Total number of captured images
|
|
493
|
+
processCompleted: boolean; // If the process was completed
|
|
494
|
+
backCaptureSkipped?: boolean; // If back capture was skipped
|
|
491
495
|
};
|
|
492
496
|
}
|
|
493
497
|
|
|
494
498
|
interface Status {
|
|
495
|
-
isVideoActive: boolean; //
|
|
496
|
-
captureStep: 'front' | 'back' | 'completed'; //
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
isModelPreloaded: boolean; // Si el modelo está precargado
|
|
499
|
+
isVideoActive: boolean; // If the camera is active
|
|
500
|
+
captureStep: 'front' | 'back' | 'completed'; // Current process step
|
|
501
|
+
hasImages: boolean; // If there are captured images
|
|
502
|
+
isProcessCompleted: boolean; // If the process is completed
|
|
503
|
+
isModelPreloaded: boolean; // If the model is preloaded
|
|
501
504
|
}
|
|
502
505
|
```
|
|
503
506
|
|
|
504
|
-
##
|
|
505
|
-
|
|
506
|
-
###
|
|
507
|
-
1. **
|
|
508
|
-
2. **
|
|
509
|
-
3. **
|
|
510
|
-
4. **
|
|
511
|
-
5. **
|
|
512
|
-
6. **
|
|
513
|
-
|
|
514
|
-
###
|
|
515
|
-
1. **
|
|
516
|
-
2. **
|
|
517
|
-
3. **
|
|
518
|
-
4. **
|
|
519
|
-
5. **
|
|
520
|
-
- **
|
|
521
|
-
- **
|
|
522
|
-
6. **
|
|
523
|
-
|
|
524
|
-
###
|
|
525
|
-
1. **
|
|
526
|
-
2. **
|
|
527
|
-
3. **
|
|
528
|
-
4. **
|
|
529
|
-
- **
|
|
530
|
-
- **
|
|
531
|
-
5. **
|
|
532
|
-
|
|
533
|
-
###
|
|
534
|
-
|
|
535
|
-
####
|
|
536
|
-
|
|
537
|
-
- **
|
|
538
|
-
- **
|
|
539
|
-
- **
|
|
540
|
-
- **
|
|
541
|
-
|
|
542
|
-
####
|
|
543
|
-
|
|
544
|
-
- **
|
|
545
|
-
- **
|
|
546
|
-
- **
|
|
547
|
-
- **
|
|
548
|
-
|
|
549
|
-
####
|
|
550
|
-
- **
|
|
551
|
-
- **
|
|
552
|
-
- **
|
|
553
|
-
|
|
554
|
-
##
|
|
555
|
-
|
|
556
|
-
- **
|
|
557
|
-
- **
|
|
558
|
-
- **
|
|
559
|
-
|
|
560
|
-
##
|
|
561
|
-
|
|
562
|
-
###
|
|
563
|
-
-
|
|
564
|
-
- No
|
|
565
|
-
-
|
|
566
|
-
-
|
|
567
|
-
-
|
|
568
|
-
|
|
569
|
-
###
|
|
570
|
-
- **
|
|
571
|
-
- **
|
|
572
|
-
- **
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
### Clonar el repositorio
|
|
507
|
+
## Workflow
|
|
508
|
+
|
|
509
|
+
### Standard Flow (useDocumentClassification = false)
|
|
510
|
+
1. **Initialization**: Component prepares for detection
|
|
511
|
+
2. **Start capture**: Detection model loads automatically
|
|
512
|
+
3. **Front capture**: User positions document and it captures automatically
|
|
513
|
+
4. **Back request**: Always requests to flip document for back capture
|
|
514
|
+
5. **Skip back button**: Available to manually skip back capture
|
|
515
|
+
6. **Completed**: Emits `captureCompleted` event with corresponding images
|
|
516
|
+
|
|
517
|
+
### Smart Classification Flow (useDocumentClassification = true)
|
|
518
|
+
1. **Initialization**: Component prepares for detection
|
|
519
|
+
2. **Start capture**: Detection and classification models load automatically
|
|
520
|
+
3. **Front capture**: User positions document and it captures automatically
|
|
521
|
+
4. **Automatic classification**: System determines if document requires back capture
|
|
522
|
+
5. **Adaptive flow**:
|
|
523
|
+
- **If passport**: Process completes automatically (no back side)
|
|
524
|
+
- **If other document**: Requests to flip document for back capture
|
|
525
|
+
6. **Completed**: Emits `captureCompleted` event with corresponding images
|
|
526
|
+
|
|
527
|
+
### Preload Flow (Recommended)
|
|
528
|
+
1. **Model preload**: Call `preloadModel()` to load models in memory
|
|
529
|
+
2. **Optimized start**: When starting capture, uses already loaded models
|
|
530
|
+
3. **Front capture**: Faster detection and classification with preloaded models
|
|
531
|
+
4. **Smart flow**:
|
|
532
|
+
- **Document without back**: Process completed immediately
|
|
533
|
+
- **Document with back**: Requests back capture
|
|
534
|
+
5. **Completed**: Emits `captureCompleted` event with all images
|
|
535
|
+
|
|
536
|
+
### Document Classification
|
|
537
|
+
|
|
538
|
+
#### Classification Enabled Mode (`useDocumentClassification = true`)
|
|
539
|
+
When enabled, the system automatically determines if the document requires back capture:
|
|
540
|
+
- **Passports**: Automatically skips back capture
|
|
541
|
+
- **Other documents**: Require capture of both sides (front and back)
|
|
542
|
+
- **Skip back button**: Always available for manual flexibility
|
|
543
|
+
- **Optimized loading**: Classification model downloads only when needed
|
|
544
|
+
|
|
545
|
+
#### Standard Mode (`useDocumentClassification = false`, default)
|
|
546
|
+
When disabled, behavior is lighter and more direct:
|
|
547
|
+
- **All documents**: Always requests back capture
|
|
548
|
+
- **Skip back button**: Available to manually skip capture
|
|
549
|
+
- **No classification**: Only loads detection model
|
|
550
|
+
- **Lower bandwidth usage**: Downloads only detection model
|
|
551
|
+
|
|
552
|
+
#### Performance Considerations
|
|
553
|
+
- **Classification disabled**: Faster loading and lower data usage
|
|
554
|
+
- **Classification enabled**: Smarter experience but requires additional model download
|
|
555
|
+
- **On-demand loading**: Classification model loads only when first document is captured
|
|
556
|
+
|
|
557
|
+
## System Requirements
|
|
558
|
+
|
|
559
|
+
- **Browsers**: Chrome/Edge 88+, Firefox 85+, Safari 14+
|
|
560
|
+
- **Camera**: Access to rear camera (mobile) or webcam (desktop)
|
|
561
|
+
- **Connection**: Internet connection to load detection models
|
|
562
|
+
|
|
563
|
+
## Privacy and Performance Considerations
|
|
564
|
+
|
|
565
|
+
### Privacy
|
|
566
|
+
- Images are processed locally in the browser
|
|
567
|
+
- No data is sent to external servers
|
|
568
|
+
- All processing runs completely on the client side
|
|
569
|
+
- Document classification is performed privately and locally
|
|
570
|
+
- Captured images are only available within your application context
|
|
571
|
+
|
|
572
|
+
### Resource Optimization
|
|
573
|
+
- **Conditional loading**: Only downloads necessary models based on configuration
|
|
574
|
+
- **Lazy loading**: Models load when actually needed
|
|
575
|
+
- **Browser cache**: Models are stored locally after first download
|
|
576
|
+
|
|
577
|
+
## Development
|
|
578
|
+
|
|
579
|
+
### Clone the repository
|
|
579
580
|
```bash
|
|
580
581
|
git clone [repository-url]
|
|
581
582
|
cd jaak-stamps-webcomponent
|
|
582
583
|
```
|
|
583
584
|
|
|
584
|
-
###
|
|
585
|
+
### Install dependencies
|
|
585
586
|
```bash
|
|
586
587
|
npm install
|
|
587
588
|
```
|
|
588
589
|
|
|
589
|
-
###
|
|
590
|
+
### Local development
|
|
590
591
|
```bash
|
|
591
592
|
npm start
|
|
592
593
|
```
|
|
593
594
|
|
|
594
|
-
###
|
|
595
|
+
### Build for production
|
|
595
596
|
```bash
|
|
596
597
|
npm run build
|
|
597
598
|
```
|
|
598
599
|
|
|
599
|
-
###
|
|
600
|
+
### Run tests
|
|
600
601
|
```bash
|
|
601
602
|
npm test
|
|
602
603
|
```
|
|
603
604
|
|
|
604
|
-
##
|
|
605
|
+
## Support
|
|
605
606
|
|
|
606
|
-
|
|
607
|
+
To report bugs or request features, please create an issue in the project repository.
|
|
607
608
|
|
|
608
|
-
##
|
|
609
|
+
## License
|
|
609
610
|
|
|
610
|
-
MIT License -
|
|
611
|
+
MIT License - see LICENSE file for details.
|