@jaak.ai/stamps 1.0.0 → 2.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +469 -450
- package/dist/cjs/index-DGM9-FNg.js +1402 -0
- package/dist/cjs/index-DGM9-FNg.js.map +1 -0
- package/dist/cjs/index.cjs.js +3 -0
- package/dist/cjs/index.cjs.js.map +1 -0
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +27 -0
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js.map +1 -0
- package/dist/cjs/jaak-stamps.cjs.entry.js +925 -0
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -0
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -0
- package/dist/cjs/loader.cjs.js +8 -15
- package/dist/cjs/loader.cjs.js.map +1 -0
- package/dist/collection/collection-manifest.json +3 -22
- package/dist/collection/components/my-component/my-component.css +530 -0
- package/dist/collection/components/my-component/my-component.js +1162 -0
- package/dist/collection/components/my-component/my-component.js.map +1 -0
- package/dist/collection/index.js +2 -1
- package/dist/collection/index.js.map +1 -0
- package/dist/collection/utils/utils.js +4 -0
- package/dist/collection/utils/utils.js.map +1 -0
- package/dist/components/index.d.ts +33 -0
- package/dist/components/index.js +1195 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/jaak-stamps.d.ts +11 -0
- package/dist/components/jaak-stamps.js +971 -0
- package/dist/components/jaak-stamps.js.map +1 -0
- package/dist/esm/index-DqoVMnc7.js +1393 -0
- package/dist/esm/index-DqoVMnc7.js.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/jaak-stamps-webcomponent.js +23 -0
- package/dist/esm/jaak-stamps-webcomponent.js.map +1 -0
- package/dist/esm/jaak-stamps.entry.js +923 -0
- package/dist/esm/jaak-stamps.entry.js.map +1 -0
- package/dist/esm/loader.js +9 -14
- package/dist/esm/loader.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/index.esm.js +2 -0
- package/dist/jaak-stamps-webcomponent/index.esm.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +2 -0
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/loader.esm.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/p-DqoVMnc7.js +3 -0
- package/dist/jaak-stamps-webcomponent/p-DqoVMnc7.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/p-dd6cc14e.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-dd6cc14e.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +119 -0
- package/dist/types/components.d.ts +50 -1382
- package/dist/types/index.d.ts +10 -1
- package/dist/types/stencil-public-runtime.d.ts +93 -28
- package/dist/types/utils/utils.d.ts +1 -0
- package/loader/cdn.js +1 -3
- package/loader/index.cjs.js +1 -3
- package/loader/index.d.ts +5 -2
- package/loader/index.es2017.js +1 -3
- package/loader/index.js +1 -3
- package/package.json +22 -26
- package/dist/cjs/document-detector_19.cjs.entry.js +0 -8630
- package/dist/cjs/index-5e4e5e7d.js +0 -1685
- package/dist/cjs/mb-tooltip.cjs.entry.js +0 -26
- package/dist/cjs/stamps.cjs.js +0 -23
- package/dist/collection/components/document-detector/document-detector.css +0 -156
- package/dist/collection/components/document-detector/document-detector.js +0 -504
- package/dist/collection/components/shared/mb-api-process-status/mb-api-process-status.css +0 -360
- package/dist/collection/components/shared/mb-api-process-status/mb-api-process-status.js +0 -124
- package/dist/collection/components/shared/mb-button/mb-button.css +0 -95
- package/dist/collection/components/shared/mb-button/mb-button.js +0 -201
- package/dist/collection/components/shared/mb-button-classic/mb-button-classic.css +0 -100
- package/dist/collection/components/shared/mb-button-classic/mb-button-classic.js +0 -130
- package/dist/collection/components/shared/mb-camera-experience/mb-camera-experience.css +0 -740
- package/dist/collection/components/shared/mb-camera-experience/mb-camera-experience.js +0 -827
- package/dist/collection/components/shared/mb-camera-experience/mb-camera-experience.utils.js +0 -55
- package/dist/collection/components/shared/mb-camera-selection/mb-camera-selection.css +0 -124
- package/dist/collection/components/shared/mb-camera-selection/mb-camera-selection.js +0 -194
- package/dist/collection/components/shared/mb-camera-toolbar/mb-camera-toolbar.css +0 -80
- package/dist/collection/components/shared/mb-camera-toolbar/mb-camera-toolbar.js +0 -275
- package/dist/collection/components/shared/mb-completed/mb-completed.css +0 -17
- package/dist/collection/components/shared/mb-completed/mb-completed.js +0 -48
- package/dist/collection/components/shared/mb-component/mb-component.css +0 -321
- package/dist/collection/components/shared/mb-component/mb-component.js +0 -2294
- package/dist/collection/components/shared/mb-component/mb-component.utils.js +0 -14
- package/dist/collection/components/shared/mb-container/mb-container.css +0 -7
- package/dist/collection/components/shared/mb-container/mb-container.js +0 -23
- package/dist/collection/components/shared/mb-feedback/mb-feedback.css +0 -36
- package/dist/collection/components/shared/mb-feedback/mb-feedback.js +0 -91
- package/dist/collection/components/shared/mb-feedback/mb-feedback.utils.js +0 -11
- package/dist/collection/components/shared/mb-help/mb-help.css +0 -191
- package/dist/collection/components/shared/mb-help/mb-help.js +0 -409
- package/dist/collection/components/shared/mb-help/mb-help.model.js +0 -5
- package/dist/collection/components/shared/mb-image-box/mb-image-box.css +0 -78
- package/dist/collection/components/shared/mb-image-box/mb-image-box.js +0 -150
- package/dist/collection/components/shared/mb-modal/mb-modal.css +0 -106
- package/dist/collection/components/shared/mb-modal/mb-modal.js +0 -239
- package/dist/collection/components/shared/mb-overlay/mb-overlay.css +0 -46
- package/dist/collection/components/shared/mb-overlay/mb-overlay.js +0 -76
- package/dist/collection/components/shared/mb-progress-tracker/mb-progress-tracker.css +0 -24
- package/dist/collection/components/shared/mb-progress-tracker/mb-progress-tracker.js +0 -80
- package/dist/collection/components/shared/mb-screen/mb-screen.css +0 -19
- package/dist/collection/components/shared/mb-screen/mb-screen.js +0 -48
- package/dist/collection/components/shared/mb-spinner/mb-spinner.css +0 -30
- package/dist/collection/components/shared/mb-spinner/mb-spinner.js +0 -67
- package/dist/collection/components/shared/mb-tooltip/mb-tooltip.css +0 -62
- package/dist/collection/components/shared/mb-tooltip/mb-tooltip.js +0 -150
- package/dist/collection/components/shared/mb-tooltip-advanced/mb-tooltip-advanced.css +0 -91
- package/dist/collection/components/shared/mb-tooltip-advanced/mb-tooltip-advanced.js +0 -96
- package/dist/collection/utils/data-structures.js +0 -189
- package/dist/collection/utils/device.helpers.js +0 -37
- package/dist/collection/utils/error-structures.js +0 -47
- package/dist/collection/utils/generic.helpers.js +0 -82
- package/dist/collection/utils/sdk.service.js +0 -943
- package/dist/collection/utils/state-lifter.js +0 -3
- package/dist/collection/utils/status.document-detector.js +0 -15
- package/dist/collection/utils/translation.service.js +0 -97
- package/dist/esm/document-detector_19.entry.js +0 -8608
- package/dist/esm/index-dc740acb.js +0 -1656
- package/dist/esm/mb-tooltip.entry.js +0 -22
- package/dist/esm/polyfills/core-js.js +0 -11
- package/dist/esm/polyfills/css-shim.js +0 -1
- package/dist/esm/polyfills/dom.js +0 -79
- package/dist/esm/polyfills/es5-html-element.js +0 -1
- package/dist/esm/polyfills/index.js +0 -34
- package/dist/esm/polyfills/system.js +0 -6
- package/dist/esm/stamps.js +0 -18
- package/dist/stamps/index.esm.js +0 -0
- package/dist/stamps/p-7f07a434.js +0 -2
- package/dist/stamps/p-ae1d9117.entry.js +0 -9
- package/dist/stamps/p-ec3f5972.entry.js +0 -1
- package/dist/stamps/stamps.esm.js +0 -1
- package/dist/types/components/document-detector/document-detector.d.ts +0 -103
- package/dist/types/components/shared/mb-api-process-status/mb-api-process-status.d.ts +0 -30
- package/dist/types/components/shared/mb-button/mb-button.d.ts +0 -41
- package/dist/types/components/shared/mb-button-classic/mb-button-classic.d.ts +0 -27
- package/dist/types/components/shared/mb-camera-experience/mb-camera-experience.d.ts +0 -141
- package/dist/types/components/shared/mb-camera-experience/mb-camera-experience.utils.d.ts +0 -3
- package/dist/types/components/shared/mb-camera-selection/mb-camera-selection.d.ts +0 -33
- package/dist/types/components/shared/mb-camera-toolbar/mb-camera-toolbar.d.ts +0 -54
- package/dist/types/components/shared/mb-completed/mb-completed.d.ts +0 -12
- package/dist/types/components/shared/mb-component/mb-component.d.ts +0 -310
- package/dist/types/components/shared/mb-component/mb-component.utils.d.ts +0 -3
- package/dist/types/components/shared/mb-container/mb-container.d.ts +0 -8
- package/dist/types/components/shared/mb-feedback/mb-feedback.d.ts +0 -19
- package/dist/types/components/shared/mb-feedback/mb-feedback.utils.d.ts +0 -2
- package/dist/types/components/shared/mb-help/mb-help.d.ts +0 -66
- package/dist/types/components/shared/mb-help/mb-help.model.d.ts +0 -9
- package/dist/types/components/shared/mb-image-box/mb-image-box.d.ts +0 -35
- package/dist/types/components/shared/mb-modal/mb-modal.d.ts +0 -53
- package/dist/types/components/shared/mb-overlay/mb-overlay.d.ts +0 -17
- package/dist/types/components/shared/mb-progress-tracker/mb-progress-tracker.d.ts +0 -19
- package/dist/types/components/shared/mb-screen/mb-screen.d.ts +0 -12
- package/dist/types/components/shared/mb-spinner/mb-spinner.d.ts +0 -16
- package/dist/types/components/shared/mb-tooltip/mb-tooltip.d.ts +0 -10
- package/dist/types/components/shared/mb-tooltip-advanced/mb-tooltip-advanced.d.ts +0 -7
- package/dist/types/utils/data-structures.d.ts +0 -264
- package/dist/types/utils/device.helpers.d.ts +0 -7
- package/dist/types/utils/error-structures.d.ts +0 -44
- package/dist/types/utils/generic.helpers.d.ts +0 -21
- package/dist/types/utils/sdk.service.d.ts +0 -52
- package/dist/types/utils/state-lifter.d.ts +0 -3
- package/dist/types/utils/status.document-detector.d.ts +0 -14
- package/dist/types/utils/translation.service.d.ts +0 -77
- package/loader/package.json +0 -11
package/README.md
CHANGED
|
@@ -1,533 +1,552 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Jaak Stamps - Document Detector Web Component
|
|
2
2
|
|
|
3
|
-
](https://stenciljs.com)
|
|
4
|
+
|
|
5
|
+
Un componente web para la detección y captura automática de documentos de identificación usando visión artificial y redes neuronales.
|
|
6
|
+
|
|
7
|
+
## Características
|
|
8
|
+
|
|
9
|
+
- 📷 **Detección automática** de documentos de identificación en tiempo real
|
|
10
|
+
- 🎯 **Guía visual** para posicionamiento óptimo del documento
|
|
11
|
+
- 📋 **Captura doble cara** (frente y reverso) con opción de omitir reverso
|
|
12
|
+
- 🖼 **Doble salida** para cada lado: imagen completa y recorte del documento
|
|
13
|
+
- 🔧 **API programática** para control total del proceso
|
|
14
|
+
- 📱 **Responsive** y compatible con dispositivos móviles
|
|
15
|
+
- ⚡ **Optimización automática** usando ONNX Runtime Web
|
|
5
16
|
|
|
6
17
|
## Instalación
|
|
7
18
|
|
|
19
|
+
### NPM
|
|
8
20
|
```bash
|
|
9
21
|
npm install @jaak.ai/stamps
|
|
10
22
|
```
|
|
11
23
|
|
|
24
|
+
### Yarn
|
|
25
|
+
```bash
|
|
26
|
+
yarn add @jaak.ai/stamps
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### CDN
|
|
30
|
+
```html
|
|
31
|
+
<script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
|
|
32
|
+
```
|
|
33
|
+
|
|
12
34
|
## Uso Básico
|
|
13
35
|
|
|
14
|
-
### HTML
|
|
36
|
+
### HTML Vanilla
|
|
15
37
|
|
|
16
38
|
```html
|
|
17
39
|
<!DOCTYPE html>
|
|
18
40
|
<html>
|
|
19
41
|
<head>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/@jaak.ai/stamps/dist/stamps/stamps.esm.js"></script>
|
|
23
|
-
<script nomodule src="https://cdn.jsdelivr.net/npm/@jaak.ai/stamps/dist/stamps/stamps.js"></script>
|
|
42
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
43
|
+
<script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
|
|
24
44
|
</head>
|
|
25
45
|
<body>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
<jaak-stamps id="detector" debug="false"></jaak-stamps>
|
|
47
|
+
|
|
48
|
+
<button onclick="startCapture()">Iniciar Captura</button>
|
|
49
|
+
<button onclick="stopCapture()">Detener</button>
|
|
50
|
+
<button onclick="resetCapture()">Reiniciar</button>
|
|
51
|
+
|
|
52
|
+
<script>
|
|
53
|
+
const detector = document.getElementById('detector');
|
|
54
|
+
|
|
55
|
+
// Escuchar evento de captura completada
|
|
56
|
+
detector.addEventListener('captureCompleted', (event) => {
|
|
57
|
+
console.log('Captura completada:', event.detail);
|
|
58
|
+
// event.detail contiene las imágenes capturadas
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Escuchar evento de componente listo
|
|
62
|
+
detector.addEventListener('isReady', (event) => {
|
|
63
|
+
console.log('Componente listo:', event.detail);
|
|
64
|
+
// event.detail indica si el componente está listo (true/false)
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
function startCapture() {
|
|
68
|
+
detector.startCapture();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function stopCapture() {
|
|
72
|
+
detector.stopCapture();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function resetCapture() {
|
|
76
|
+
detector.resetCapture();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Precargar el modelo (opcional - mejora el rendimiento)
|
|
80
|
+
async function preloadModel() {
|
|
81
|
+
try {
|
|
82
|
+
const result = await detector.preloadModel();
|
|
83
|
+
console.log('Modelo precargado:', result);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('Error al precargar:', error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Obtener imágenes después de la captura
|
|
90
|
+
async function getImages() {
|
|
91
|
+
try {
|
|
92
|
+
const images = await detector.getCapturedImages();
|
|
93
|
+
console.log('Imágenes capturadas:', images);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error('Error:', error.message);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</script>
|
|
47
99
|
</body>
|
|
48
100
|
</html>
|
|
49
101
|
```
|
|
50
102
|
|
|
51
|
-
###
|
|
52
|
-
|
|
53
|
-
```jsx
|
|
54
|
-
import React, { useEffect, useRef } from 'react';
|
|
55
|
-
import '@jaak.ai/stamps';
|
|
56
|
-
|
|
57
|
-
function DocumentDetectorComponent() {
|
|
58
|
-
const detectorRef = useRef(null);
|
|
59
|
-
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
const detector = detectorRef.current;
|
|
62
|
-
|
|
63
|
-
// Escuchar los eventos emitidos directamente por el componente
|
|
64
|
-
const handleStatus = (ev) => {
|
|
65
|
-
console.log('Estado del detector:', ev.detail);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const handleResults = (ev) => {
|
|
69
|
-
console.log('Resultados del escaneo:', ev.detail);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
detector.addEventListener('status', handleStatus);
|
|
73
|
-
detector.addEventListener('results', handleResults);
|
|
74
|
-
|
|
75
|
-
// Iniciar el escaneo por cámara cuando el componente esté listo
|
|
76
|
-
setTimeout(() => {
|
|
77
|
-
detector.startCameraScan();
|
|
78
|
-
}, 1000);
|
|
79
|
-
|
|
80
|
-
return () => {
|
|
81
|
-
detector.removeEventListener('status', handleStatus);
|
|
82
|
-
detector.removeEventListener('results', handleResults);
|
|
83
|
-
};
|
|
84
|
-
}, []);
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<document-detector
|
|
88
|
-
ref={detectorRef}
|
|
89
|
-
license-key="TU_CLAVE_DE_LICENCIA"
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
103
|
+
### Angular
|
|
93
104
|
|
|
94
|
-
|
|
105
|
+
#### 1. Instalar el componente
|
|
106
|
+
```bash
|
|
107
|
+
npm install @jaak.ai/stamps
|
|
95
108
|
```
|
|
96
109
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
licenseKey: 'TU_CLAVE_DE_LICENCIA'
|
|
115
|
-
};
|
|
116
|
-
},
|
|
117
|
-
methods: {
|
|
118
|
-
// Métodos para manejar los eventos emitidos directamente por el componente
|
|
119
|
-
handleStatus(ev) {
|
|
120
|
-
console.log('Estado del detector:', ev.detail);
|
|
121
|
-
},
|
|
122
|
-
handleResults(ev) {
|
|
123
|
-
console.log('Resultados del escaneo:', ev.detail);
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
mounted() {
|
|
127
|
-
const detector = this.$refs.detector;
|
|
128
|
-
|
|
129
|
-
// Escuchar los eventos emitidos directamente por el componente
|
|
130
|
-
detector.addEventListener('status', this.handleStatus);
|
|
131
|
-
detector.addEventListener('results', this.handleResults);
|
|
132
|
-
|
|
133
|
-
// Iniciar el escaneo por cámara cuando el componente esté listo
|
|
134
|
-
setTimeout(() => {
|
|
135
|
-
detector.startCameraScan();
|
|
136
|
-
}, 1000);
|
|
137
|
-
},
|
|
138
|
-
beforeUnmount() {
|
|
139
|
-
const detector = this.$refs.detector;
|
|
140
|
-
|
|
141
|
-
// Eliminar los event listeners
|
|
142
|
-
detector.removeEventListener('status', this.handleStatus);
|
|
143
|
-
detector.removeEventListener('results', this.handleResults);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
</script>
|
|
110
|
+
#### 2. Configurar el módulo (app.module.ts)
|
|
111
|
+
```typescript
|
|
112
|
+
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
113
|
+
import { BrowserModule } from '@angular/platform-browser';
|
|
114
|
+
import { AppComponent } from './app.component';
|
|
115
|
+
|
|
116
|
+
// Importar el componente web
|
|
117
|
+
import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js';
|
|
118
|
+
|
|
119
|
+
@NgModule({
|
|
120
|
+
declarations: [AppComponent],
|
|
121
|
+
imports: [BrowserModule],
|
|
122
|
+
providers: [],
|
|
123
|
+
bootstrap: [AppComponent],
|
|
124
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA] // Permitir elementos personalizados
|
|
125
|
+
})
|
|
126
|
+
export class AppModule { }
|
|
147
127
|
```
|
|
148
128
|
|
|
149
|
-
|
|
150
|
-
|
|
129
|
+
#### 3. Usar en el componente
|
|
151
130
|
```typescript
|
|
152
|
-
//
|
|
153
|
-
import { Component,
|
|
154
|
-
import '@jaak.ai/stamps';
|
|
131
|
+
// app.component.ts
|
|
132
|
+
import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
|
|
155
133
|
|
|
156
134
|
@Component({
|
|
157
|
-
selector: 'app-
|
|
135
|
+
selector: 'app-root',
|
|
158
136
|
template: `
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
137
|
+
<div class="container">
|
|
138
|
+
<h1>Detector de Documentos</h1>
|
|
139
|
+
|
|
140
|
+
<jaak-stamps
|
|
141
|
+
#detector
|
|
142
|
+
[debug]="false"
|
|
143
|
+
(captureCompleted)="onCaptureCompleted($event)"
|
|
144
|
+
(isReady)="onComponentReady($event)">
|
|
145
|
+
</jaak-stamps>
|
|
146
|
+
|
|
147
|
+
<div class="controls">
|
|
148
|
+
<button (click)="preloadModel()">Precargar Modelo</button>
|
|
149
|
+
<button (click)="startCapture()">Iniciar Captura</button>
|
|
150
|
+
<button (click)="stopCapture()">Detener</button>
|
|
151
|
+
<button (click)="resetCapture()">Reiniciar</button>
|
|
152
|
+
<button (click)="getImages()" [disabled]="!isCompleted">Obtener Imágenes</button>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div *ngIf="capturedData" class="results">
|
|
156
|
+
<h3>Imágenes Capturadas:</h3>
|
|
157
|
+
<p>Total de imágenes: {{ capturedData.metadata.totalImages }}</p>
|
|
158
|
+
<img *ngIf="capturedData.front.cropped" [src]="capturedData.front.cropped" alt="Frente">
|
|
159
|
+
<img *ngIf="capturedData.back.cropped" [src]="capturedData.back.cropped" alt="Reverso">
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
`,
|
|
163
|
+
styles: [`
|
|
164
|
+
.container { max-width: 800px; margin: 0 auto; padding: 20px; }
|
|
165
|
+
.controls { margin: 20px 0; }
|
|
166
|
+
.controls button { margin: 0 10px; padding: 10px 20px; }
|
|
167
|
+
.results img { max-width: 300px; margin: 10px; border: 1px solid #ccc; }
|
|
168
|
+
`]
|
|
164
169
|
})
|
|
165
|
-
export class
|
|
166
|
-
@ViewChild('detector') detectorRef
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
export class AppComponent implements OnInit {
|
|
171
|
+
@ViewChild('detector', { static: true }) detectorRef!: ElementRef;
|
|
172
|
+
|
|
173
|
+
capturedData: any = null;
|
|
174
|
+
isCompleted = false;
|
|
175
|
+
|
|
176
|
+
ngOnInit() {
|
|
177
|
+
// El elemento ya está disponible después de la vista
|
|
172
178
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
179
|
+
|
|
180
|
+
async preloadModel() {
|
|
181
|
+
try {
|
|
182
|
+
const result = await this.detectorRef.nativeElement.preloadModel();
|
|
183
|
+
console.log('Modelo precargado:', result);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error('Error al precargar modelo:', error);
|
|
186
|
+
}
|
|
176
187
|
}
|
|
177
188
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// Iniciar el escaneo por cámara cuando el componente esté listo
|
|
186
|
-
setTimeout(() => {
|
|
187
|
-
detector.startCameraScan();
|
|
188
|
-
}, 1000);
|
|
189
|
+
async startCapture() {
|
|
190
|
+
try {
|
|
191
|
+
await this.detectorRef.nativeElement.startCapture();
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('Error al iniciar captura:', error);
|
|
194
|
+
}
|
|
189
195
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// Eliminar los event listeners
|
|
195
|
-
detector.removeEventListener('status', this.handleStatus.bind(this));
|
|
196
|
-
detector.removeEventListener('results', this.handleResults.bind(this));
|
|
196
|
+
|
|
197
|
+
async stopCapture() {
|
|
198
|
+
await this.detectorRef.nativeElement.stopCapture();
|
|
197
199
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
```tsx
|
|
204
|
-
import { Component, h, State, Listen, Element } from '@stencil/core';
|
|
205
|
-
import '@jaak.ai/stamps';
|
|
206
|
-
|
|
207
|
-
@Component({
|
|
208
|
-
tag: 'app-document-detector',
|
|
209
|
-
styleUrl: 'app-document-detector.css',
|
|
210
|
-
shadow: true
|
|
211
|
-
})
|
|
212
|
-
export class AppDocumentDetector {
|
|
213
|
-
@Element() el: HTMLElement;
|
|
214
|
-
@State() results: any = null;
|
|
215
|
-
@State() status: string = '';
|
|
216
|
-
|
|
217
|
-
// Escuchar los eventos emitidos directamente por el componente
|
|
218
|
-
@Listen('status')
|
|
219
|
-
handleStatus(ev: CustomEvent) {
|
|
220
|
-
this.status = ev.detail;
|
|
221
|
-
console.log('Estado del detector:', this.status);
|
|
200
|
+
|
|
201
|
+
async resetCapture() {
|
|
202
|
+
await this.detectorRef.nativeElement.resetCapture();
|
|
203
|
+
this.capturedData = null;
|
|
204
|
+
this.isCompleted = false;
|
|
222
205
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
206
|
+
|
|
207
|
+
async getImages() {
|
|
208
|
+
try {
|
|
209
|
+
const images = await this.detectorRef.nativeElement.getCapturedImages();
|
|
210
|
+
console.log('Imágenes obtenidas:', images);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Error al obtener imágenes:', error);
|
|
213
|
+
}
|
|
228
214
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
detector.startCameraScan();
|
|
235
|
-
}, 1000);
|
|
215
|
+
|
|
216
|
+
onCaptureCompleted(event: any) {
|
|
217
|
+
console.log('Captura completada en Angular:', event.detail);
|
|
218
|
+
this.capturedData = event.detail;
|
|
219
|
+
this.isCompleted = true;
|
|
236
220
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<document-detector
|
|
242
|
-
license-key="TU_CLAVE_DE_LICENCIA"
|
|
243
|
-
/>
|
|
244
|
-
</div>
|
|
245
|
-
);
|
|
221
|
+
|
|
222
|
+
onComponentReady(event: any) {
|
|
223
|
+
console.log('Componente listo en Angular:', event.detail);
|
|
224
|
+
// El componente está listo para iniciar detección
|
|
246
225
|
}
|
|
247
226
|
}
|
|
248
227
|
```
|
|
249
228
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
El componente `document-detector` es el elemento principal de esta librería, diseñado para proporcionar una experiencia completa de escaneo e identificación de documentos en aplicaciones web.
|
|
253
|
-
|
|
254
|
-
### Descripción General
|
|
255
|
-
|
|
256
|
-
El `document-detector` es un componente web que utiliza tecnología de reconocimiento óptico avanzada para escanear y extraer información de documentos de identidad. Está construido sobre el SDK BlinkID y ofrece una interfaz fácil de usar para integrar capacidades de escaneo de documentos en cualquier aplicación web.
|
|
257
|
-
|
|
258
|
-
### Características Principales
|
|
259
|
-
|
|
260
|
-
- **Escaneo en tiempo real**: Captura documentos de identidad a través de la cámara del dispositivo.
|
|
261
|
-
- **Procesamiento de imágenes**: Permite cargar imágenes de documentos para su análisis.
|
|
262
|
-
- **Soporte para documentos de doble cara**: Puede procesar ambos lados de documentos como identificaciones o licencias de conducir.
|
|
263
|
-
- **Extracción de datos**: Obtiene automáticamente información como nombre, fecha de nacimiento, número de documento, etc.
|
|
264
|
-
- **Captura de imágenes**: Guarda imágenes del documento, rostro y firma cuando están disponibles.
|
|
265
|
-
- **Interfaz personalizable**: Permite adaptar la apariencia y comportamiento a las necesidades de tu aplicación.
|
|
266
|
-
- **Eventos detallados**: Proporciona eventos para cada etapa del proceso de escaneo.
|
|
267
|
-
- **Modo dinámico**: Optimiza automáticamente el rendimiento según el dispositivo (escritorio o móvil).
|
|
268
|
-
- **Filtros de calidad ajustables**: Controla la rigurosidad de los filtros de desenfoque y brillo.
|
|
269
|
-
- **Traducciones personalizables**: Permite personalizar todos los mensajes mostrados al usuario.
|
|
270
|
-
- **Capacidad de reinicio**: Facilita reiniciar el componente sin necesidad de recargarlo.
|
|
271
|
-
|
|
272
|
-
### Ciclo de Vida del Componente
|
|
273
|
-
|
|
274
|
-
1. **Inicialización**: El componente carga el SDK y prepara los reconocedores.
|
|
275
|
-
2. **Detección**: Busca un documento en el campo visual de la cámara o en la imagen proporcionada.
|
|
276
|
-
3. **Análisis**: Procesa el documento detectado para extraer la información.
|
|
277
|
-
4. **Resultados**: Emite los datos extraídos y las imágenes capturadas.
|
|
278
|
-
|
|
279
|
-
### Casos de Uso Comunes
|
|
280
|
-
|
|
281
|
-
- **Verificación de identidad**: Para procesos de onboarding digital o KYC (Know Your Customer).
|
|
282
|
-
- **Registro de usuarios**: Automatización de la captura de datos personales.
|
|
283
|
-
- **Check-in digital**: En hoteles, eventos o instalaciones que requieren identificación.
|
|
284
|
-
- **Servicios financieros**: Para apertura de cuentas o solicitudes de crédito.
|
|
285
|
-
- **Servicios de salud**: Registro de pacientes y verificación de seguros.
|
|
286
|
-
|
|
287
|
-
### Ejemplo de Implementación Básica
|
|
229
|
+
### React
|
|
288
230
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
</document-detector>
|
|
293
|
-
|
|
294
|
-
<!-- O usando la propiedad config con opciones avanzadas -->
|
|
295
|
-
<document-detector
|
|
296
|
-
config='{
|
|
297
|
-
"key": "TU_CLAVE_DE_LICENCIA",
|
|
298
|
-
"dynamicMode": true,
|
|
299
|
-
"strictMode": true,
|
|
300
|
-
"translation": {
|
|
301
|
-
"front": "Escanea el frente de tu documento",
|
|
302
|
-
"back": "Ahora escanea el reverso",
|
|
303
|
-
"changeSide": "Voltea el documento",
|
|
304
|
-
"cameraFeedbackBlur": "El documento está borroso",
|
|
305
|
-
"cameraFeedbackGlare": "Evita el reflejo en el documento"
|
|
306
|
-
}
|
|
307
|
-
}'>
|
|
308
|
-
</document-detector>
|
|
231
|
+
#### 1. Instalar el componente
|
|
232
|
+
```bash
|
|
233
|
+
npm install @jaak.ai/stamps
|
|
309
234
|
```
|
|
310
235
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
236
|
+
#### 2. Crear componente wrapper (opcional pero recomendado)
|
|
237
|
+
```jsx
|
|
238
|
+
// JaakStampsWrapper.jsx
|
|
239
|
+
import React, { useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
|
|
240
|
+
|
|
241
|
+
// Importar el web component
|
|
242
|
+
import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js';
|
|
243
|
+
|
|
244
|
+
const JaakStampsWrapper = forwardRef(({ debug = false, onCaptureCompleted, onIsReady }, ref) => {
|
|
245
|
+
const elementRef = useRef(null);
|
|
246
|
+
|
|
247
|
+
useImperativeHandle(ref, () => ({
|
|
248
|
+
preloadModel: () => elementRef.current?.preloadModel(),
|
|
249
|
+
startCapture: () => elementRef.current?.startCapture(),
|
|
250
|
+
stopCapture: () => elementRef.current?.stopCapture(),
|
|
251
|
+
resetCapture: () => elementRef.current?.resetCapture(),
|
|
252
|
+
getCapturedImages: () => elementRef.current?.getCapturedImages(),
|
|
253
|
+
getStatus: () => elementRef.current?.getStatus(),
|
|
254
|
+
skipBackCapture: () => elementRef.current?.skipBackCapture(),
|
|
255
|
+
isProcessCompleted: () => elementRef.current?.isProcessCompleted()
|
|
256
|
+
}));
|
|
257
|
+
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
const element = elementRef.current;
|
|
260
|
+
|
|
261
|
+
const handleCaptureCompleted = (event) => {
|
|
262
|
+
if (onCaptureCompleted) {
|
|
263
|
+
onCaptureCompleted(event.detail);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const handleIsReady = (event) => {
|
|
268
|
+
if (onIsReady) {
|
|
269
|
+
onIsReady(event.detail);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
if (element) {
|
|
274
|
+
element.addEventListener('captureCompleted', handleCaptureCompleted);
|
|
275
|
+
element.addEventListener('isReady', handleIsReady);
|
|
276
|
+
|
|
277
|
+
return () => {
|
|
278
|
+
element.removeEventListener('captureCompleted', handleCaptureCompleted);
|
|
279
|
+
element.removeEventListener('isReady', handleIsReady);
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}, [onCaptureCompleted, onIsReady]);
|
|
283
|
+
|
|
284
|
+
return (
|
|
285
|
+
<jaak-stamps
|
|
286
|
+
ref={elementRef}
|
|
287
|
+
debug={debug}
|
|
288
|
+
/>
|
|
289
|
+
);
|
|
353
290
|
});
|
|
354
291
|
|
|
355
|
-
|
|
356
|
-
detector.addEventListener('results', (event) => {
|
|
357
|
-
const resultados = event.detail;
|
|
358
|
-
console.log('Datos del documento:', resultados);
|
|
359
|
-
|
|
360
|
-
// Acceder a imágenes del documento (si están disponibles)
|
|
361
|
-
if (resultados.generalData && resultados.generalData.documentImage) {
|
|
362
|
-
const imagenFrente = resultados.generalData.documentImage.front;
|
|
363
|
-
const imagenReverso = resultados.generalData.documentImage.back;
|
|
364
|
-
const imagenRostro = resultados.generalData.documentImage.face;
|
|
365
|
-
|
|
366
|
-
// Hacer algo con las imágenes...
|
|
367
|
-
}
|
|
368
|
-
});
|
|
292
|
+
export default JaakStampsWrapper;
|
|
369
293
|
```
|
|
370
294
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
// Iniciar escaneo por cámara
|
|
377
|
-
function iniciarEscaneoCamara() {
|
|
378
|
-
detector.startCameraScan();
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// Iniciar escaneo desde archivo de imagen
|
|
382
|
-
function escanearDesdeImagen(archivo) {
|
|
383
|
-
detector.startImageScan(archivo);
|
|
384
|
-
}
|
|
295
|
+
#### 3. Usar en tu aplicación React
|
|
296
|
+
```jsx
|
|
297
|
+
// App.jsx
|
|
298
|
+
import React, { useRef, useState } from 'react';
|
|
299
|
+
import JaakStampsWrapper from './components/JaakStampsWrapper';
|
|
385
300
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
301
|
+
function App() {
|
|
302
|
+
const detectorRef = useRef(null);
|
|
303
|
+
const [capturedData, setCapturedData] = useState(null);
|
|
304
|
+
const [isCompleted, setIsCompleted] = useState(false);
|
|
305
|
+
const [status, setStatus] = useState(null);
|
|
306
|
+
|
|
307
|
+
const handleCaptureCompleted = (data) => {
|
|
308
|
+
console.log('Captura completada:', data);
|
|
309
|
+
setCapturedData(data);
|
|
310
|
+
setIsCompleted(true);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const handleIsReady = (isReady) => {
|
|
314
|
+
console.log('Componente listo:', isReady);
|
|
315
|
+
// El componente está listo para iniciar detección
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const preloadModel = async () => {
|
|
319
|
+
try {
|
|
320
|
+
const result = await detectorRef.current?.preloadModel();
|
|
321
|
+
console.log('Modelo precargado:', result);
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.error('Error al precargar modelo:', error);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const startCapture = async () => {
|
|
328
|
+
try {
|
|
329
|
+
await detectorRef.current?.startCapture();
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error('Error al iniciar captura:', error);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const stopCapture = async () => {
|
|
336
|
+
await detectorRef.current?.stopCapture();
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const resetCapture = async () => {
|
|
340
|
+
await detectorRef.current?.resetCapture();
|
|
341
|
+
setCapturedData(null);
|
|
342
|
+
setIsCompleted(false);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const getImages = async () => {
|
|
346
|
+
try {
|
|
347
|
+
const images = await detectorRef.current?.getCapturedImages();
|
|
348
|
+
console.log('Imágenes obtenidas:', images);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
console.error('Error al obtener imágenes:', error);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const checkStatus = async () => {
|
|
355
|
+
const currentStatus = await detectorRef.current?.getStatus();
|
|
356
|
+
setStatus(currentStatus);
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
return (
|
|
360
|
+
<div className="App">
|
|
361
|
+
<header className="App-header">
|
|
362
|
+
<h1>Detector de Documentos - React</h1>
|
|
363
|
+
|
|
364
|
+
<JaakStampsWrapper
|
|
365
|
+
ref={detectorRef}
|
|
366
|
+
debug={false}
|
|
367
|
+
onCaptureCompleted={handleCaptureCompleted}
|
|
368
|
+
onIsReady={handleIsReady}
|
|
369
|
+
/>
|
|
370
|
+
|
|
371
|
+
<div className="controls">
|
|
372
|
+
<button onClick={preloadModel}>Precargar Modelo</button>
|
|
373
|
+
<button onClick={startCapture}>Iniciar Captura</button>
|
|
374
|
+
<button onClick={stopCapture}>Detener</button>
|
|
375
|
+
<button onClick={resetCapture}>Reiniciar</button>
|
|
376
|
+
<button onClick={getImages} disabled={!isCompleted}>
|
|
377
|
+
Obtener Imágenes
|
|
378
|
+
</button>
|
|
379
|
+
<button onClick={checkStatus}>Verificar Estado</button>
|
|
380
|
+
</div>
|
|
381
|
+
|
|
382
|
+
{status && (
|
|
383
|
+
<div className="status">
|
|
384
|
+
<h3>Estado Actual:</h3>
|
|
385
|
+
<p>Video activo: {status.isVideoActive ? 'Sí' : 'No'}</p>
|
|
386
|
+
<p>Paso: {status.captureStep}</p>
|
|
387
|
+
<p>Mensaje: {status.statusMessage}</p>
|
|
388
|
+
<p>Proceso completado: {status.isProcessCompleted ? 'Sí' : 'No'}</p>
|
|
389
|
+
<p>Modelo precargado: {status.isModelPreloaded ? 'Sí' : 'No'}</p>
|
|
390
|
+
</div>
|
|
391
|
+
)}
|
|
392
|
+
|
|
393
|
+
{capturedData && (
|
|
394
|
+
<div className="results">
|
|
395
|
+
<h3>Resultados de la Captura:</h3>
|
|
396
|
+
<p>Total de imágenes: {capturedData.metadata.totalImages}</p>
|
|
397
|
+
<p>Timestamp: {capturedData.timestamp}</p>
|
|
398
|
+
|
|
399
|
+
{capturedData.front.cropped && (
|
|
400
|
+
<div>
|
|
401
|
+
<h4>Frente del Documento:</h4>
|
|
402
|
+
<img
|
|
403
|
+
src={capturedData.front.cropped}
|
|
404
|
+
alt="Frente del documento"
|
|
405
|
+
style={{ maxWidth: '300px', border: '1px solid #ccc', margin: '10px' }}
|
|
406
|
+
/>
|
|
407
|
+
</div>
|
|
408
|
+
)}
|
|
409
|
+
|
|
410
|
+
{capturedData.back.cropped && (
|
|
411
|
+
<div>
|
|
412
|
+
<h4>Reverso del Documento:</h4>
|
|
413
|
+
<img
|
|
414
|
+
src={capturedData.back.cropped}
|
|
415
|
+
alt="Reverso del documento"
|
|
416
|
+
style={{ maxWidth: '300px', border: '1px solid #ccc', margin: '10px' }}
|
|
417
|
+
/>
|
|
418
|
+
</div>
|
|
419
|
+
)}
|
|
420
|
+
</div>
|
|
421
|
+
)}
|
|
422
|
+
</header>
|
|
423
|
+
</div>
|
|
424
|
+
);
|
|
391
425
|
}
|
|
392
426
|
|
|
393
|
-
|
|
394
|
-
document.getElementById('inputImagen').addEventListener('change', (event) => {
|
|
395
|
-
if (event.target.files && event.target.files[0]) {
|
|
396
|
-
escanearDesdeImagen(event.target.files[0]);
|
|
397
|
-
}
|
|
398
|
-
});
|
|
427
|
+
export default App;
|
|
399
428
|
```
|
|
400
429
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
El componente puede personalizarse mediante CSS utilizando las partes expuestas a través de Shadow DOM:
|
|
430
|
+
## API Reference
|
|
404
431
|
|
|
405
|
-
|
|
406
|
-
document-detector::part(mb-camera-video) {
|
|
407
|
-
border-radius: 16px;
|
|
408
|
-
border: 2px solid #3498db;
|
|
409
|
-
}
|
|
410
|
-
```
|
|
432
|
+
### Props/Atributos
|
|
411
433
|
|
|
412
|
-
|
|
434
|
+
| Propiedad | Tipo | Predeterminado | Descripción |
|
|
435
|
+
|-----------|------|---------------|-------------|
|
|
436
|
+
| `debug` | `boolean` | `false` | Activa el modo debug para mostrar información de depuración |
|
|
437
|
+
| `alignmentTolerance` | `number` | `10` | Tolerancia en píxeles para considerar un lado alineado |
|
|
413
438
|
|
|
414
|
-
|
|
415
|
-
- **HTTPS**: Para usar la funcionalidad de cámara, tu aplicación debe servirse a través de HTTPS.
|
|
416
|
-
- **Compatibilidad**: Verifica la compatibilidad con navegadores móviles si tu aplicación está orientada a dispositivos móviles.
|
|
417
|
-
- **Licencia**: Se requiere una clave de licencia válida para el funcionamiento del componente.
|
|
439
|
+
### Métodos Públicos
|
|
418
440
|
|
|
419
|
-
|
|
441
|
+
| Método | Retorna | Descripción |
|
|
442
|
+
|--------|---------|-------------|
|
|
443
|
+
| `startCapture()` | `Promise<void>` | Inicia el proceso de detección y captura |
|
|
444
|
+
| `stopCapture()` | `Promise<void>` | Detiene el proceso y libera la cámara |
|
|
445
|
+
| `resetCapture()` | `Promise<void>` | Reinicia el proceso de captura |
|
|
446
|
+
| `preloadModel()` | `Promise<{success: boolean, message?: string, error?: string}>` | Precarga el modelo de detección |
|
|
447
|
+
| `getCapturedImages()` | `Promise<CapturedImages>` | Obtiene las imágenes capturadas (solo después de completar) |
|
|
448
|
+
| `isProcessCompleted()` | `Promise<boolean>` | Verifica si el proceso ha sido completado |
|
|
449
|
+
| `getStatus()` | `Promise<Status>` | Obtiene el estado actual del detector |
|
|
450
|
+
| `skipBackCapture()` | `Promise<void>` | Omite la captura del reverso (solo disponible en paso 'back') |
|
|
420
451
|
|
|
421
|
-
###
|
|
452
|
+
### Eventos
|
|
422
453
|
|
|
423
|
-
|
|
454
|
+
| Evento | Payload | Descripción |
|
|
455
|
+
|--------|---------|-------------|
|
|
456
|
+
| `captureCompleted` | `CapturedImages` | Se emite cuando se completa el proceso de captura |
|
|
457
|
+
| `isReady` | `boolean` | Se emite cuando el componente está listo para comenzar la detección (modelo ONNX cargado) |
|
|
424
458
|
|
|
425
|
-
|
|
426
|
-
|--------------------------|-------------------------------------------|--------------------------------------------|
|
|
427
|
-
| `license-key` | string | Clave de licencia para el SDK |
|
|
428
|
-
| `config` | object | Configuración del componente (ver detalle abajo) |
|
|
459
|
+
### Tipos de Datos
|
|
429
460
|
|
|
430
|
-
|
|
461
|
+
```typescript
|
|
462
|
+
interface CapturedImages {
|
|
463
|
+
front: {
|
|
464
|
+
fullFrame: string | null; // Base64 de la imagen completa del frente
|
|
465
|
+
cropped: string | null; // Base64 del documento recortado del frente
|
|
466
|
+
};
|
|
467
|
+
back: {
|
|
468
|
+
fullFrame: string | null; // Base64 de la imagen completa del reverso
|
|
469
|
+
cropped: string | null; // Base64 del documento recortado del reverso
|
|
470
|
+
};
|
|
471
|
+
timestamp: string; // ISO timestamp de la captura
|
|
472
|
+
metadata: {
|
|
473
|
+
totalImages: number; // Número total de imágenes capturadas
|
|
474
|
+
processCompleted: boolean; // Si el proceso fue completado
|
|
475
|
+
backCaptureSkipped?: boolean; // Si se omitió la captura del reverso
|
|
476
|
+
};
|
|
477
|
+
}
|
|
431
478
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
479
|
+
interface Status {
|
|
480
|
+
isVideoActive: boolean; // Si la cámara está activa
|
|
481
|
+
captureStep: 'front' | 'back' | 'completed'; // Paso actual del proceso
|
|
482
|
+
statusMessage: string; // Mensaje de estado actual
|
|
483
|
+
hasImages: boolean; // Si hay imágenes capturadas
|
|
484
|
+
isProcessCompleted: boolean; // Si el proceso está completado
|
|
485
|
+
isModelPreloaded: boolean; // Si el modelo está precargado
|
|
486
|
+
}
|
|
487
|
+
```
|
|
438
488
|
|
|
439
|
-
|
|
489
|
+
## Flujo de Trabajo
|
|
440
490
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
| `cameraFeedbackBlur` | string | Mensaje cuando el documento está borroso |
|
|
448
|
-
| `cameraFeedbackFacePhotoCovered`| string | Mensaje cuando la foto de la cara está cubierta |
|
|
449
|
-
| `cameraFeedbackGlare` | string | Mensaje cuando hay deslumbramiento en el documento |
|
|
450
|
-
| `cameraFeedbackWrongSide` | string | Mensaje cuando se muestra el lado incorrecto del documento |
|
|
451
|
-
| `moveCloser` | string | Mensaje para acercar el documento |
|
|
452
|
-
| `moveFarther` | string | Mensaje para alejar el documento |
|
|
491
|
+
### Flujo Estándar
|
|
492
|
+
1. **Inicialización**: El componente se prepara para la detección
|
|
493
|
+
2. **Inicio de captura**: Se carga el modelo ONNX automáticamente al iniciar la detección
|
|
494
|
+
3. **Captura del frente**: El usuario posiciona el documento y se captura automáticamente
|
|
495
|
+
4. **Captura del reverso**: Se solicita voltear el documento para capturar el reverso
|
|
496
|
+
5. **Completado**: Se emite el evento `captureCompleted` con todas las imágenes
|
|
453
497
|
|
|
454
|
-
###
|
|
498
|
+
### Flujo con Precarga (Recomendado)
|
|
499
|
+
1. **Precarga del modelo**: Se llama a `preloadModel()` para cargar el modelo en memoria
|
|
500
|
+
2. **Inicio optimizado**: Al iniciar la captura, se usa el modelo ya cargado
|
|
501
|
+
3. **Captura del frente**: Detección más rápida con el modelo precargado
|
|
502
|
+
4. **Captura del reverso**: Se solicita voltear el documento
|
|
503
|
+
5. **Completado**: Se emite el evento `captureCompleted` con todas las imágenes
|
|
455
504
|
|
|
456
|
-
|
|
505
|
+
## Requisitos del Sistema
|
|
457
506
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
| `results` | any | Resultados del escaneo |
|
|
507
|
+
- **Navegadores**: Chrome/Edge 88+, Firefox 85+, Safari 14+
|
|
508
|
+
- **Cámara**: Acceso a cámara trasera (móvil) o webcam (escritorio)
|
|
509
|
+
- **Conexión**: Conexión a internet para cargar el modelo ONNX Runtime
|
|
462
510
|
|
|
463
|
-
|
|
511
|
+
## Consideraciones de Privacidad
|
|
464
512
|
|
|
465
|
-
|
|
513
|
+
- Las imágenes se procesan localmente en el navegador
|
|
514
|
+
- No se envían datos a servidores externos
|
|
515
|
+
- El modelo de IA se ejecuta completamente en el cliente
|
|
516
|
+
- Las imágenes capturadas solo están disponibles en el contexto de tu aplicación
|
|
466
517
|
|
|
467
|
-
|
|
468
|
-
|-------------------------|--------------------------------------------|--------------------- |-------------------------------------------|
|
|
469
|
-
| `setUiState` | state: "ERROR" \| "LOADING" \| "NONE" \| "SUCCESS" | Promise<void> | Establecer el estado UI del componente |
|
|
470
|
-
| `startCameraScan` | Ninguno | Promise<void> | Inicia el escaneo utilizando la cámara |
|
|
471
|
-
| `startImageScan` | file: File | Promise<void> | Inicia el escaneo utilizando una imagen |
|
|
472
|
-
| `startMultiSideImageScan` | firstFile: File, secondFile: File | Promise<void> | Inicia el escaneo utilizando dos imágenes para documentos de doble cara |
|
|
473
|
-
| `setUiMessage` | state: "FEEDBACK_ERROR" \| "FEEDBACK_INFO" \| "FEEDBACK_OK", message: string | Promise<void> | Establecer un mensaje UI |
|
|
474
|
-
| `getProductIntegrationInfo` | Ninguno | Promise<ProductIntegrationInfo> | Obtener información de integración del producto |
|
|
475
|
-
| `restartComponent` | Ninguno | Promise<void> | Reinicia el componente y vuelve a iniciar el escaneo por cámara |
|
|
518
|
+
## Desarrollo
|
|
476
519
|
|
|
477
|
-
|
|
520
|
+
### Clonar el repositorio
|
|
521
|
+
```bash
|
|
522
|
+
git clone [repository-url]
|
|
523
|
+
cd jaak-stamps-webcomponent
|
|
524
|
+
```
|
|
478
525
|
|
|
479
|
-
|
|
526
|
+
### Instalar dependencias
|
|
527
|
+
```bash
|
|
528
|
+
npm install
|
|
529
|
+
```
|
|
480
530
|
|
|
481
|
-
###
|
|
531
|
+
### Desarrollo local
|
|
532
|
+
```bash
|
|
533
|
+
npm start
|
|
534
|
+
```
|
|
482
535
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
ERROR = "ERROR",
|
|
487
|
-
RUNNING = "RUNNING",
|
|
488
|
-
INITIALIZING = "INITIALIZING",
|
|
489
|
-
FRONT_SIDE_DETECTION = "FRONT_SIDE_DETECTION",
|
|
490
|
-
BACK_SIDE_DETECTION = "BACK_SIDE_DETECTION",
|
|
491
|
-
DOCUMENT_NOT_FOUND = "DOCUMENT_NOT_FOUND",
|
|
492
|
-
DOCUMENT_DETECTED = "DOCUMENT_DETECTED",
|
|
493
|
-
CHANGE_SIDE = "CHANGE_SIDE",
|
|
494
|
-
RESULTS_SUCCESS = "RESULTS_SUCCESS",
|
|
495
|
-
RESULTS_EMPTY = "RESULTS_EMPTY",
|
|
496
|
-
DETECTION_FAILED = "DETECTION_FAILED"
|
|
497
|
-
}
|
|
536
|
+
### Construir para producción
|
|
537
|
+
```bash
|
|
538
|
+
npm run build
|
|
498
539
|
```
|
|
499
540
|
|
|
500
|
-
###
|
|
541
|
+
### Ejecutar tests
|
|
542
|
+
```bash
|
|
543
|
+
npm test
|
|
544
|
+
```
|
|
501
545
|
|
|
502
|
-
|
|
546
|
+
## Soporte
|
|
503
547
|
|
|
504
|
-
|
|
505
|
-
interface DocumentData {
|
|
506
|
-
generalData: {
|
|
507
|
-
type: string;
|
|
508
|
-
nationality: string;
|
|
509
|
-
name: string;
|
|
510
|
-
surname: string;
|
|
511
|
-
address: string;
|
|
512
|
-
birthDate: string;
|
|
513
|
-
gender: string;
|
|
514
|
-
documentImage: {
|
|
515
|
-
frontFull: string; // Imagen base64
|
|
516
|
-
backFull: string; // Imagen base64
|
|
517
|
-
front: string; // Imagen base64
|
|
518
|
-
back: string; // Imagen base64
|
|
519
|
-
signature: string; // Imagen base64
|
|
520
|
-
face: string; // Imagen base64
|
|
521
|
-
}
|
|
522
|
-
};
|
|
523
|
-
mechanicalReadingZone: string;
|
|
524
|
-
specificData: Array<{
|
|
525
|
-
label: string;
|
|
526
|
-
value: string;
|
|
527
|
-
}>;
|
|
528
|
-
}
|
|
529
|
-
```
|
|
548
|
+
Para reportar bugs o solicitar características, por favor crea un issue en el repositorio del proyecto.
|
|
530
549
|
|
|
531
550
|
## Licencia
|
|
532
551
|
|
|
533
|
-
MIT
|
|
552
|
+
MIT License - ver archivo LICENSE para detalles.
|