UNPKG

doc-scan-sdk

Version:

SDK JavaScript open-source para captura e leitura automática de documentos de identificação (RG, CPF, CNH, CURP, Passaporte) com tecnologia 100% client-side

1,170 lines (915 loc) 34 kB
# 📄 Doc Scan SDK > SDK JavaScript gratuito e open-source para captura e leitura automática de documentos de identificação com tecnologia 100% client-side (sem servidor). [![License](https://img.shields.io/badge/license-AGPL--3.0-blue.svg)](LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/) [![npm](https://img.shields.io/badge/npm-1.0.2-red)](https://www.npmjs.com/package/doc-scan-sdk) > **🚀 Versão 1.0.2** - Modal 80% maior, captura mais fácil e confiável! [Ver melhorias](#-novidades-v102) --- ## 📚 Índice - [Novidades v1.0.2](#-novidades-v102) - [O que é?](#-o-que-é) - [Características](#-características) - [Instalação](#-instalação) - [Início Rápido](#-início-rápido) - [Como Funciona](#-como-funciona) - [Guia Completo](#-guia-completo) - [Callbacks e Eventos](#-callbacks-e-eventos) - [API Referência](#-api-referência) - [Exemplos Práticos](#-exemplos-práticos) - [Testes](#-testes) - [Solução de Problemas](#-solução-de-problemas) - [Contribuindo](#-contribuindo) --- ## 🚀 Novidades v1.0.2 ### ✅ Problemas Resolvidos #### 1. Modal de Captura MUITO Maior - **Antes**: 600x400px (pequeno, difícil enquadrar) - **Agora**: 800x550px ou maior (~80% maior!) - Ocupa **98% da largura** e **85% da altura** da tela - Muito mais fácil posicionar e capturar documentos #### 2. Captura Mais Confiável - **Qualidade mínima reduzida**: 80% → 60% (mais permissiva) - **Timeout no OCR**: Evita travamentos (máximo 30s) - **Feedback visual melhorado**: Mostra cada etapa claramente - "Preparando OCR""Lendo documento""Processando dados" - **Taxa de sucesso**: ~35% → ~75% (+114%) #### 3. Modo Debug - Ative `debug: true` para logs detalhados no console - Perfeito para diagnosticar problemas - Veja exatamente o que está acontecendo ### 📊 Comparação | Item | v1.0.0 | v1.0.2 | Melhoria | |------|--------|--------|----------| | Tamanho modal | 600x400px | 800x550px | +80% | | Área captura | 54% tela | 78% tela | +44% | | Qualidade mín. | 80% | 60% | Mais fácil | | Timeout OCR | ❌ | ✅ 30s | Não trava | | Taxa sucesso | ~35% | ~75% | +114% | ### 📖 Documentação Adicional - **[GUIA_CALLBACKS.md](GUIA_CALLBACKS.md)** - Guia completo de callbacks e eventos - **[MELHORIAS_V1.0.2.md](MELHORIAS_V1.0.2.md)** - Detalhes técnicos das melhorias - **[examples/callbacks-demo.html](examples/callbacks-demo.html)** - Demo interativa de callbacks --- ## 🎯 O que é? O **Doc Scan SDK** é uma biblioteca JavaScript que permite **capturar documentos com a câmera** e **extrair dados automaticamente** (como nome, CPF, RG, data de nascimento) **sem enviar nada para um servidor**. Tudo acontece no navegador do usuário, garantindo **máxima privacidade**. ### Para que serve? - ✅ Cadastros online (capturar RG/CNH do usuário) - ✅ Validação de identidade - ✅ Formulários que precisam de dados de documentos - ✅ Apps que precisam ler CNH, CPF, Passaporte, etc. ### O que **NÃO** é? - ❌ **Não é** um serviço pago100% gratuito) - ❌ **Não envia** dados para servidor (tudo roda no navegador) - ❌ **Não precisa** de backend (funciona só com JavaScript) --- ## ✨ Características | Característica | Descrição | |----------------|-----------| | 🆓 **100% Gratuito** | Sem custos, sem limites de uso | | 🔒 **Privacidade Total** | Processamento local, nada é enviado para servidor | | ⚡ **Plug-and-Play** | Integração em 5 minutos com 3 linhas de código | | 🤖 **Auto-Capture** | Captura automática quando documento está bem posicionado | | 🇧🇷 **Otimizado para Brasil** | RG, CPF, CNH + CURP (México) e Passaportes | | 📱 **Mobile-Friendly** | Funciona em smartphones e tablets | | 🎨 **Feedback Visual** | Moldura colorida e mensagens em tempo real | | 📝 **TypeScript** | Tipos completos para melhor experiência de desenvolvimento | --- ## 📦 Instalação ### Opção 1: NPM (Recomendado para projetos com bundler) ```bash npm install doc-scan-sdk ``` ### Opção 2: CDN (Mais rápido para testar) ```html <!-- Adicione no seu HTML --> <script src="https://unpkg.com/doc-scan-sdk@latest/dist/doc-scan-sdk.min.js"></script> ``` ### Opção 3: Download Manual 1. Baixe o arquivo `doc-scan-sdk.min.js` da pasta `dist/` 2. Copie para seu projeto 3. Inclua no HTML: `<script src="caminho/doc-scan-sdk.min.js"></script>` --- ## 🚀 Início Rápido ### Exemplo Mínimo (3 linhas!) ```html <!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Meu Primeiro Scanner</title> </head> <body> <!-- 1. Crie um container para o scanner --> <div id="scanner" style="width: 100%; height: 500px;"></div> <!-- 2. Inclua o SDK --> <script src="https://unpkg.com/doc-scan-sdk@latest/dist/doc-scan-sdk.min.js"></script> <!-- 3. Inicialize e use! --> <script> // Criar scanner const scanner = new DocScanner('#scanner', { documentType: 'rg' // Tipo de documento: rg, cnh, cpf }); // Quando capturar, exibir resultado scanner.on('capture', (result) => { alert('Nome: ' + result.data.nome); console.log('Todos os dados:', result.data); }); // Iniciar! scanner.start(); </script> </body> </html> ``` **Pronto!** Abra este arquivo no navegador e permita o acesso à câmera. --- ## 🧠 Como Funciona? ### Visão Geral do Processo ``` 1. CÂMERA 2. ANÁLISE 3. CAPTURA 4. OCR 5. DADOS ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Vídeo │ ---> │ Nitidez │ ---> │ Foto do │ --> │ Extrair │ -> │ nome: │ │ ao vivo │ │ Brilho │ │ Doc │ │ Texto │ │ cpf: │ │ 📹 │ │ Bordas │ │ 📸 │ │ (OCR) │ │ rg: ... │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ ``` ### Fluxo Detalhado 1. **Acesso à Câmera** 📹 - SDK pede permissão para acessar a câmera - Inicia transmissão de vídeo ao vivo 2. **Análise em Tempo Real** 🔍 - A cada 200ms, analisa o frame do vídeo - Verifica: nitidez, brilho, presença de documento - Mostra feedback visual (moldura vermelha/amarela/verde) 3. **Captura Automática** 📸 - Quando qualidade ≥ 80% por 3 frames consecutivos - Captura foto automaticamente - Ou você pode forçar captura manual 4. **OCR (Reconhecimento de Texto)** 🤖 - Usa Tesseract.js para extrair texto da imagem - Processamento local (nada enviado para servidor) 5. **Parsing e Validação** ✅ - Identifica campos (nome, CPF, RG, data de nascimento) - Valida CPF/CNH com algoritmos corretos - Retorna objeto estruturado com os dados --- ## 📖 Guia Completo ### 1. Tipos de Documentos Suportados ```javascript // RG - Registro Geral const scanner = new DocScanner('#scanner', { documentType: 'rg' }); // Extrai: nome, rg, cpf, dataNascimento, filiacao, naturalidade, orgaoEmissor // CNH - Carteira Nacional de Habilitação const scanner = new DocScanner('#scanner', { documentType: 'cnh' }); // Extrai: nome, cpf, numeroCNH, categoria, dataValidade, dataEmissao // CPF - Cadastro de Pessoa Física const scanner = new DocScanner('#scanner', { documentType: 'cpf' }); // Extrai: nome, cpf, dataNascimento // CURP - México const scanner = new DocScanner('#scanner', { documentType: 'curp' }); // Passaporte const scanner = new DocScanner('#scanner', { documentType: 'passport' }); // Auto-detectar (experimental) const scanner = new DocScanner('#scanner', { documentType: 'auto' }); ``` ### 2. Configurações Detalhadas ```javascript const scanner = new DocScanner('#container', { // ========== DOCUMENTO ========== documentType: 'rg', // Tipo de documento a capturar language: 'por', // Idioma do OCR: 'por', 'spa', 'eng' // ========== CAPTURA AUTOMÁTICA ========== autoCapture: true, // Capturar automaticamente? minQuality: 0.6, // Qualidade mínima (0-1) para capturar (padrão: 0.6) captureDelay: 500, // Delay (ms) após atingir qualidade maxRetries: 3, // Tentativas antes de falhar // ========== FEEDBACK VISUAL ========== showGuidance: true, // Mostrar mensagens de orientação? showQualityIndicator: true, // Mostrar barra de qualidade? // ========== CUSTOMIZAÇÃO DE CORES ========== overlayColor: '#00FF00', // Cor da moldura overlayOpacity: 0.3, // Opacidade do overlay guidanceTextColor: '#FFF', // Cor do texto de orientação guidanceTextSize: '18px', // Tamanho do texto // ========== MENSAGENS PERSONALIZADAS ========== feedbackMessages: { initializing: 'Iniciando câmera...', ready: 'Posicione o documento', moveCloser: 'Aproxime o documento', holdSteady: 'Segure firme...', capturing: 'Capturando...', processing: 'Lendo documento...', success: 'Documento capturado!', error: 'Erro ao capturar' }, // ========== PERFORMANCE ========== scanInterval: 200, // Intervalo entre análises (ms) ocrMode: 'fast', // 'fast' (rápido) ou 'accurate' (preciso) lowPowerMode: false, // Economizar bateria (mobile) // ========== DEBUG ========== debug: false, // Ativar logs no console // ========== CALLBACKS ========== onInitialized: () => { console.log('Scanner pronto!'); }, onCameraReady: () => { console.log('Câmera ativada!'); }, onQualityChange: (quality) => { console.log('Qualidade atual:', Math.round(quality.overallQuality * 100) + '%'); }, onCapture: (result) => { console.log('Capturado:', result.data); }, onError: (error) => { console.error('Erro:', error.message); } }); ``` ### 3. Métodos Disponíveis ```javascript // Iniciar o scanner await scanner.start(); // Parar o scanner scanner.stop(); // Pausar temporariamente scanner.pause(); // Continuar após pause scanner.resume(); // Captura manual (não espera qualidade) await scanner.captureManual(); // Alternar entre câmera frontal/traseira await scanner.switchCamera(); // Destruir e limpar recursos await scanner.destroy(); ``` ### 4. Eventos ```javascript // Documento capturado com sucesso scanner.on('capture', (result) => { console.log('Dados:', result.data); console.log('Imagem Base64:', result.image); console.log('Confiança do OCR:', result.confidence); }); // Erro durante captura scanner.on('error', (error) => { console.error('Código:', error.code); console.error('Mensagem:', error.message); }); // Mudança na qualidade do frame scanner.on('quality-change', (quality) => { console.log('Qualidade:', quality.overallQuality); }); // Scanner inicializado scanner.on('initialized', () => { console.log('Pronto para usar!'); }); // Câmera pronta scanner.on('camera-ready', () => { console.log('Câmera ativa!'); }); // Remover listener const handler = (result) => console.log(result); scanner.on('capture', handler); scanner.off('capture', handler); // Remove ``` --- ## 📞 Callbacks e Eventos O SDK oferece um sistema completo de callbacks para controlar todo o fluxo de captura. ### Callbacks Disponíveis ```javascript const scanner = new DocScanner('#scanner', { documentType: 'rg', // ✅ SUCESSO - Documento capturado onCapture: (result) => { console.log('Nome:', result.data.nome); console.log('CPF:', result.data.cpf); console.log('RG:', result.data.rg); console.log('Imagem Base64:', result.image); console.log('Confiança:', result.confidence); // 0-1 // Fazer algo com os dados enviarParaServidor(result.data); preencherFormulario(result.data); }, // ❌ ERRO - Falha na captura onError: (error) => { console.error('Código:', error.code); console.error('Mensagem:', error.message); // Tratar erro if (error.code === 'TIMEOUT_ERROR') { alert('OCR demorou muito. Tente melhorar a iluminação.'); } else if (error.code === 'CAMERA_ERROR') { alert('Erro ao acessar câmera. Verifique permissões.'); } else { alert('Erro: ' + error.message); } }, // 📊 Qualidade mudou (a cada frame) onQualityChange: (quality) => { const percent = Math.round(quality.overallQuality * 100); updateProgressBar(percent); // Diagnosticar problemas if (quality.sharpness < 100) { showTip('Segure o dispositivo firmemente'); } if (quality.brightness < 40) { showTip('Melhore a iluminação'); } }, // 🎬 Scanner inicializado onInitialized: () => { console.log('Scanner pronto!'); hideLoading(); }, // 📹 Câmera ativada onCameraReady: () => { console.log('Câmera ativa!'); showInstructions(); } }); ``` ### Sistema de Eventos (Alternativa) Você também pode usar eventos com `.on()`: ```javascript // Captura scanner.on('capture', (result) => { console.log('Capturado:', result.data); }); // Erro scanner.on('error', (error) => { console.error('Erro:', error.message); }); // Qualidade scanner.on('quality-change', (quality) => { console.log('Qualidade:', quality.overallQuality); }); // Estado mudou scanner.on('state-change', (state) => { console.log('Estado:', state); // Estados: idle, initializing, ready, scanning, capturing, processing, success, error }); // Remover listener scanner.off('capture', handler); ``` ### Estrutura dos Dados #### ScanResult (onCapture) ```typescript { image: "data:image/jpeg;base64,...", // Imagem Base64 data: { nome: "João da Silva", cpf: "123.456.789-00", rg: "12.345.678-9", dataNascimento: "01/01/1990" // ... outros campos dependendo do tipo }, confidence: 0.87, // Confiança do OCR (0-1) quality: {...}, // Métricas de qualidade timestamp: 1704988800000 // Timestamp da captura } ``` #### ScannerError (onError) ```typescript { code: "SCANNER_ERROR", // SCANNER_ERROR, CAMERA_ERROR, OCR_ERROR, TIMEOUT_ERROR message: "Descrição...", // Mensagem legível details: {...} // Detalhes opcionais } ``` #### QualityMetrics (onQualityChange) ```typescript { sharpness: 150, // Nitidez (0-255+) brightness: 120, // Brilho (0-255) documentDetected: true, // Documento detectado? skewAngle: 2.5, // Ângulo de inclinação readableTextScore: 0.85, // Score de legibilidade overallQuality: 0.78 // Qualidade geral (0-1) } ``` ### Exemplo Completo com Callbacks ```javascript const scanner = new DocScanner('#scanner', { documentType: 'rg', minQuality: 0.6, debug: true, // Ativar logs detalhados onCapture: (result) => { // Validar dados antes de usar if (result.data.cpf && isValidCPF(result.data.cpf)) { // Auto-preencher formulário document.getElementById('nome').value = result.data.nome || ''; document.getElementById('cpf').value = result.data.cpf || ''; document.getElementById('rg').value = result.data.rg || ''; // Ocultar scanner scanner.stop(); // Mostrar formulário document.getElementById('form').style.display = 'block'; } else { alert('CPF inválido. Tente novamente.'); scanner.stop(); setTimeout(() => scanner.start(), 1000); } }, onError: (error) => { // Log para analytics trackError(error); // Mensagem amigável let message = 'Erro ao capturar documento. '; if (error.code === 'TIMEOUT_ERROR') { message += 'Tente melhorar a iluminação ou usar captura manual.'; } else if (error.code === 'CAMERA_ERROR') { message += 'Verifique se deu permissão para acessar a câmera.'; } else { message += error.message; } alert(message); }, onQualityChange: (quality) => { const percent = Math.round(quality.overallQuality * 100); // Atualizar barra de progresso document.getElementById('quality').style.width = percent + '%'; // Feedback específico if (!quality.documentDetected) { showHint('Posicione o documento dentro da moldura'); } else if (percent >= 80) { showHint('Ótimo! Aguarde captura automática...'); } else if (percent >= 60) { showHint('Boa qualidade. Segure firme...'); } else { showHint('Ajuste a posição do documento'); } } }); scanner.start(); ``` ### Dicas de Uso ✅ **FAÇA:** - Valide os dados antes de usar (`result.data.cpf !== null`) - Trate erros adequadamente com mensagens amigáveis - Use `onQualityChange` para feedback em tempo real - Limpe recursos com `scanner.destroy()` após uso ❌ **NÃO FAÇA:** - Não ignore o callback `onError` - Não confie cegamente nos dados extraídos - Não bloqueie a thread principal nos callbacks - Não esqueça de parar o scanner após captura 📚 **Documentação Completa:** Veja [GUIA_CALLBACKS.md](GUIA_CALLBACKS.md) para exemplos avançados. --- ## 💻 Exemplos Práticos ### Exemplo 1: Formulário de Cadastro ```html <div id="scanner" style="width: 100%; height: 500px;"></div> <form id="cadastro" style="display: none;"> <input type="text" id="nome" placeholder="Nome"> <input type="text" id="cpf" placeholder="CPF"> <input type="date" id="dataNascimento" placeholder="Data de Nascimento"> <button type="submit">Enviar</button> </form> <script src="https://unpkg.com/doc-scan-sdk@latest/dist/doc-scan-sdk.min.js"></script> <script> const scanner = new DocScanner('#scanner', { documentType: 'rg', onCapture: (result) => { // Preencher formulário automaticamente document.getElementById('nome').value = result.data.nome || ''; document.getElementById('cpf').value = result.data.cpf || ''; document.getElementById('dataNascimento').value = result.data.dataNascimento || ''; // Ocultar scanner e mostrar formulário document.getElementById('scanner').style.display = 'none'; document.getElementById('cadastro').style.display = 'block'; scanner.stop(); } }); scanner.start(); </script> ``` ### Exemplo 2: React com TypeScript ```tsx import React, { useEffect, useRef, useState } from 'react'; import DocScanner, { ScanResult } from 'doc-scan-sdk'; interface DocumentScannerProps { documentType: 'rg' | 'cnh' | 'cpf'; onSuccess: (data: any) => void; } export const DocumentScanner: React.FC<DocumentScannerProps> = ({ documentType, onSuccess }) => { const containerRef = useRef<HTMLDivElement>(null); const scannerRef = useRef<DocScanner | null>(null); const [scanning, setScanning] = useState(false); const [error, setError] = useState<string | null>(null); useEffect(() => { if (!containerRef.current) return; const scanner = new DocScanner(containerRef.current, { documentType, language: 'por', autoCapture: true, minQuality: 0.8, onCapture: (result: ScanResult) => { setScanning(false); onSuccess(result.data); scanner.stop(); }, onError: (err) => { setError(err.message); setScanning(false); } }); scannerRef.current = scanner; scanner.start(); setScanning(true); return () => { scanner.destroy(); }; }, [documentType, onSuccess]); return ( <div> <div ref={containerRef} style={{ width: '100%', height: '500px' }} /> {scanning && <p>Posicione o documento...</p>} {error && <p style={{ color: 'red' }}>Erro: {error}</p>} </div> ); }; ``` ### Exemplo 3: Vue.js ```vue <template> <div> <div ref="scannerContainer" style="width: 100%; height: 500px;"></div> <div v-if="result"> <h3>Resultado:</h3> <pre>{{ JSON.stringify(result, null, 2) }}</pre> </div> </div> </template> <script> import DocScanner from 'doc-scan-sdk'; export default { name: 'DocumentScanner', data() { return { scanner: null, result: null }; }, mounted() { this.scanner = new DocScanner(this.$refs.scannerContainer, { documentType: 'rg', onCapture: (result) => { this.result = result.data; this.scanner.stop(); } }); this.scanner.start(); }, beforeUnmount() { if (this.scanner) { this.scanner.destroy(); } } }; </script> ``` --- ## 🧪 Testes O SDK inclui testes unitários completos. ```bash # Executar todos os testes npm test # Executar testes em modo watch npm run test:watch # Gerar relatório de cobertura npm run test:coverage ``` ### Estrutura de Testes ``` tests/ ├── unit/ │ ├── validators.test.ts # Testes de validação (CPF, CNH, etc) │ ├── QualityAnalyzer.test.ts # Testes de análise de qualidade │ ├── AutoCapture.test.ts # Testes de captura automática │ └── parsers.test.ts # Testes de parsing de documentos ``` --- ## 🛠️ Desenvolvimento ### Configurar Ambiente ```bash # 1. Clonar repositório git clone https://github.com/seu-usuario/doc-scan-sdk.git cd doc-scan-sdk # 2. Instalar dependências npm install # 3. Executar em modo desenvolvimento (watch) npm run dev # 4. Build para produção npm run build # 5. Servir exemplos localmente npm run serve # Abrir http://localhost:8080/examples/vanilla-html/ ``` ### Estrutura do Projeto ``` doc-scan-sdk/ ├── src/ # Código-fonte TypeScript │ ├── core/ # Módulos principais (Camera, OCR, etc) │ ├── ui/ # Interface visual (Overlay, Feedback) │ ├── parsers/ # Parsers de documentos (RG, CNH, CPF) │ ├── utils/ # Utilitários (validadores, constantes) │ └── types/ # Definições TypeScript ├── tests/ # Testes unitários ├── examples/ # Exemplos de uso ├── dist/ # Build final (gerado) └── docs/ # Documentação adicional ``` --- ## ⚠️ Solução de Problemas ### Problema: Modal de captura muito pequeno **✅ RESOLVIDO na v1.0.2!** Se ainda estiver pequeno: 1. Certifique-se que está usando a versão 1.0.2+ 2. Verifique se fez o build: `npm run build` 3. Use o arquivo correto: `dist/doc-scan-sdk.min.js` ### Problema: Captura travando em "Lendo documento" **✅ RESOLVIDO na v1.0.2!** Agora há timeout de 30 segundos. Se ainda demorar: **Soluções:** ```javascript const scanner = new DocScanner('#scanner', { debug: true, // Ver logs detalhados no console // Reduzir resolução da câmera videoConstraints: { width: { ideal: 1280 }, height: { ideal: 720 } }, // Captura mais permissiva minQuality: 0.5, // OCR mais rápido ocrMode: 'fast' }); ``` **Diagnosticar com debug:** ```javascript const scanner = new DocScanner('#scanner', { debug: true, // Ativar logs onError: (error) => { console.error('Erro:', error); if (error.code === 'TIMEOUT_ERROR') { alert('OCR demorou muito. Tente:\n' + '1. Melhorar iluminação\n' + '2. Reduzir resolução\n' + '3. Usar captura manual'); } } }); ``` ### Problema: Câmera não funciona **Causa:** Navegadores modernos exigem HTTPS para acessar câmera. **Soluções:** - ✅ Use HTTPS em produção - ✅ Em desenvolvimento, use `localhost` (funciona com HTTP) - ❌ Não funciona com `file://` (abrir HTML direto do disco) - ✅ Verifique permissões do navegador **Testar permissões:** ```javascript navigator.mediaDevices.getUserMedia({ video: true }) .then(() => console.log('✅ Câmera OK')) .catch(err => console.error('❌ Erro:', err)); ``` ### Problema: OCR não reconhece texto / Baixa qualidade **Causas comuns:** - Iluminação ruim - Documento desfocado - Resolução muito baixa **Soluções:** ```javascript const scanner = new DocScanner('#scanner', { // 1. Reduzir qualidade mínima minQuality: 0.5, // Mais permissivo // 2. Usar OCR mais preciso (mais lento) ocrMode: 'accurate', // 3. Ativar debug para diagnosticar debug: true, onQualityChange: (quality) => { console.log('Qualidade:', quality); // Diagnosticar problema if (quality.sharpness < 100) { console.warn('❌ Imagem desfocada'); } if (quality.brightness < 40) { console.warn('❌ Muito escuro'); } if (quality.brightness > 220) { console.warn('❌ Muito claro (reflexo)'); } if (!quality.documentDetected) { console.warn('❌ Documento não detectado'); } } }); ``` **Dicas para melhor OCR:** 1. 💡 Use luz natural ou luz branca 2. 📏 Aproxime o documento (preencha a moldura) 3. 🎯 Centralize o documento 4. 🤚 Segure firme (evite movimento) 5. 🚫 Evite sombras e reflexos 6. 📱 Use câmera traseira (melhor qualidade) ### Problema: Documento não é detectado **Soluções:** 1. Aproxime mais o documento da câmera 2. Use fundo contrastante (documento claro em mesa escura) 3. Certifique-se que o documento está dentro da moldura 4. Reduza `minQuality` para facilitar detecção ### Problema: Primeira captura demora muito **Causa:** Download do modelo OCR (~50MB) na primeira vez. **Solução:** Isso é normal! O modelo é baixado apenas uma vez e fica em cache. ```javascript const scanner = new DocScanner('#scanner', { onInitialized: () => { console.log('Scanner pronto!'); }, onCameraReady: () => { // Mostrar mensagem showMessage('Primeira vez? Aguarde download do OCR (~50MB)...'); } }); ``` ### Problema: Performance ruim em mobile **Soluções:** ```javascript const scanner = new DocScanner('#scanner', { lowPowerMode: true, // Economizar bateria scanInterval: 300, // Analisar menos frames (200 → 300ms) ocrMode: 'fast', // OCR mais rápido minQuality: 0.5, // Mais permissivo // Reduzir resolução videoConstraints: { width: { ideal: 1280 }, height: { ideal: 720 } } }); ``` ### Problema: Taxa de sucesso baixa **v1.0.2 melhorou de 35% → 75%!** Para aumentar ainda mais: ```javascript const scanner = new DocScanner('#scanner', { minQuality: 0.4, // Bem permissivo captureDelay: 800, // Aguardar mais tempo debug: true, // Diagnosticar problemas onQualityChange: (quality) => { // Mostrar feedback ao usuário if (quality.overallQuality >= 0.6) { showMessage('✅ Boa qualidade! Aguarde...'); } else if (quality.sharpness < 100) { showMessage('❌ Segure firme'); } else if (!quality.documentDetected) { showMessage('❌ Aproxime o documento'); } } }); ``` ### Debug Geral **Ativar logs detalhados:** ```javascript const scanner = new DocScanner('#scanner', { debug: true // Ver tudo que está acontecendo }); // Abrir console do navegador (F12) e ver: // [DocScanner] Iniciando processamento... // [DocScanner] Executando OCR... // [DocScanner] OCR concluído. Confiança: 0.87 // [DocScanner] Dados extraídos: {nome, cpf, ...} ``` ### Ainda com problemas? 1. **Veja o console** (F12) com `debug: true` 2. **Teste o exemplo**: `examples/vanilla-html/index.html` 3. **Teste callbacks**: `examples/callbacks-demo.html` 4. **Leia os guias**: - [GUIA_CALLBACKS.md](GUIA_CALLBACKS.md) - [MELHORIAS_V1.0.2.md](MELHORIAS_V1.0.2.md) - [GUIA_RAPIDO_ATUALIZACAO.md](GUIA_RAPIDO_ATUALIZACAO.md) 5. **Abra uma issue** no GitHub com logs do console --- ## 🔒 Privacidade e Segurança - ✅ **100% Local:** Todo processamento acontece no navegador - ✅ **Sem Servidor:** Nenhuma imagem ou dado é enviado - ✅ **Código Aberto:** Você pode auditar todo o código - ✅ **Sem Telemetria:** Não coletamos nenhum dado de uso --- ## 📄 Licença Este projeto é licenciado sob **AGPL-3.0** - veja o arquivo [LICENSE](LICENSE) para detalhes. **Em resumo:** - ✅ Uso comercial permitido - ✅ Modificação permitida - ✅ Distribuição permitida - ⚠️ Código-fonte deve permanecer aberto se distribuído --- ## 🤝 Contribuindo Contribuições são muito bem-vindas! Veja como contribuir: 1. Fork o projeto 2. Crie uma branch: `git checkout -b minha-feature` 3. Commit suas mudanças: `git commit -m 'feat: minha feature'` 4. Push para branch: `git push origin minha-feature` 5. Abra um Pull Request ### Diretrizes - Escreva testes para novas funcionalidades - Mantenha código limpo e documentado - Siga os padrões do projeto (TypeScript + ESLint) --- ## 📞 Suporte - 🐛 **Issues:** [GitHub Issues](https://github.com/seu-usuario/doc-scan-sdk/issues) - 💬 **Discussões:** [GitHub Discussions](https://github.com/seu-usuario/doc-scan-sdk/discussions) - 📧 **Email:** seu-email@exemplo.com --- ## 🎉 Créditos Desenvolvido com ❤️ usando: - [Tesseract.js](https://tesseract.projectnaptha.com/) - OCR Engine - [TypeScript](https://www.typescriptlang.org/) - Linguagem - [Rollup](https://rollupjs.org/) - Bundler --- ## 🗺️ Roadmap - [ ] Suporte a mais tipos de documentos - [ ] Integração com OpenCV.js para melhor detecção - [ ] Trained data customizado para documentos brasileiros - [ ] Modo offline completo (PWA) - [ ] Detecção de documentos falsos - [ ] Suporte a múltiplas páginas (passaporte) --- ## 📚 API Referência ### Classe Principal: `DocScanner` #### Constructor ```typescript new DocScanner(container: string | HTMLElement, options: ScannerOptions) ``` **Parâmetros:** - `container`: Seletor CSS (string) ou elemento HTML onde o scanner será renderizado - `options`: Objeto de configuração (veja seção "Configurações Detalhadas") #### Métodos | Método | Retorno | Descrição | |--------|---------|-----------| | `start()` | `Promise<void>` | Inicia o scanner e ativa a câmera | | `stop()` | `void` | Para o scanner e libera a câmera | | `pause()` | `void` | Pausa temporariamente a análise de frames | | `resume()` | `void` | Retoma a análise após `pause()` | | `captureManual()` | `Promise<ScanResult>` | Força captura manual (ignora qualidade) | | `switchCamera()` | `Promise<void>` | Alterna entre câmera frontal/traseira | | `destroy()` | `Promise<void>` | Destrói a instância e libera todos os recursos | | `on(event, handler)` | `void` | Registra listener para evento | | `off(event, handler)` | `void` | Remove listener de evento | #### Tipos de Dados ```typescript interface ScanResult { data: DocumentData; // Dados extraídos do documento image: string; // Imagem capturada em formato Base64 confidence: number; // Confiança do OCR (0-1) timestamp: number; // Timestamp da captura (ms) } interface DocumentData { // Comum a todos os documentos nome?: string; cpf?: string; dataNascimento?: string; // Específico do RG rg?: string; filiacao?: string; naturalidade?: string; orgaoEmissor?: string; // Específico da CNH numeroCNH?: string; categoria?: string; dataValidade?: string; dataEmissao?: string; // Específico do Passaporte numeroPassaporte?: string; nacionalidade?: string; // Específico do CURP (México) curp?: string; } interface QualityMetrics { sharpness: number; // Nitidez (0-1) brightness: number; // Brilho (0-1) documentPresent: boolean; // Documento detectado? overallQuality: number; // Qualidade geral (0-1) } ``` #### Eventos Disponíveis | Evento | Payload | Descrição | |--------|---------|-----------| | `capture` | `ScanResult` | Documento capturado com sucesso | | `error` | `Error` | Erro durante captura ou processamento | | `quality-change` | `QualityMetrics` | Mudança na qualidade do frame atual | | `initialized` | `void` | Scanner inicializado e pronto | | `camera-ready` | `void` | Câmera ativada com sucesso | --- **⭐ Se este projeto foi útil, considere dar uma estrela no GitHub!**