Javascript QR Code Scanner baseado na porta javascript de Cosmo Wolfe da biblioteca ZXing do Google.
Nesta biblioteca, diversas melhorias foram aplicadas em relação à porta original:
BarcodeDetector
nativo estiver disponível, apenas ~15,3 kB (~5,6 kB compactados com gzip) serão carregados.De acordo com nosso benchmarking, a taxa de detecção do mecanismo de scanner deste projeto é cerca de 2 a 3 vezes (e até 8 vezes) maior que a mais popular biblioteca de scanner QR javascript LazarSoft/jsqrcode. Além disso, a outra biblioteca muitas vezes lê mal o conteúdo dos códigos QR, enquanto para este projeto não ocorreram leituras erradas no benchmarking.
A biblioteca suporta a digitalização de um fluxo de vídeo contínuo de uma webcam, bem como a digitalização de imagens únicas.
O desenvolvimento desta biblioteca é patrocinado pela nimiq, o primeiro blockchain baseado em navegador do mundo.
Consulte https://nimiq.github.io/qr-scanner/demo/
Para instalar via npm:
npm install --save qr-scanner
Para instalar via fio:
yarn add qr-scanner
Ou simplesmente copie qr-scanner.min.js
e qr-scanner-worker.min.js
para o seu projeto.
O QR Scanner consiste em dois arquivos principais. qr-scanner.min.js
é o arquivo API principal que carrega o script de trabalho qr-scanner-worker.min.js
por meio de uma importação dinâmica, somente se necessário. Se você não estiver usando um empacotador como Rollup ou Webpack que lida com importações dinâmicas automaticamente, talvez seja necessário copiar qr-scanner-worker.min.js
para seu dist, próximo a qr-scanner.min.js
ou próximo ao script no qual você está agrupando qr-scanner.min.js
.
qr-scanner.min.js
é um módulo es6 e pode ser importado da seguinte forma:
import QrScanner from 'path/to/qr-scanner.min.js' ; // if using plain es6 import
import QrScanner from 'qr-scanner' ; // if installed via package and bundling with a module bundler like webpack or rollup
Isso requer que o script de importação também seja um módulo es6 ou uma tag de script de módulo, por exemplo:
< script type =" module " >
import QrScanner from 'path/to/qr-scanner.min.js' ;
// do something with QrScanner
</ script >
Se o seu projeto não for baseado em módulos es6 você pode
import ( 'path/to/qr-scanner.min.js' ) . then ( ( module ) => {
const QrScanner = module . default ;
// do something with QrScanner
} ) ;
qr-scanner.umd.min.js
para uso direto como script sem módulo < script src =" path/to/qr-scanner.umd.min.js " > </ script >
< script >
// do something with QrScanner
</ script >
qr-scanner.umd.min.js
diretamente com seu código sem módulo com ferramentas como gulp ou grunt.require
como browserify: const QrScanner = require ( 'qr-scanner' ) ; // if installed via package
const QrScanner = require ( 'path/to/qr-scanner.umd.min.js' ) ; // if not installed via package
// do something with QrScanner
Esta biblioteca usa recursos do ECMAScript 2017, como funções async
. Se precisar oferecer suporte a navegadores antigos, você pode usar qr-scanner.legacy.min.js
, que é compatível com ECMAScript 2015 (ES6). É uma construção UMD e pode ser usada como um substituto para qr-scanner.umd.min.js
, veja acima. Observe que a construção legada é maior, pois inclui alguns polyfills e, para oferecer suporte a navegadores que não suportam importações dinâmicas, inline o script de trabalho que, no entanto, seria necessário para ser carregado em navegadores legados de qualquer maneira. Provavelmente, você não precisará usar a versão legada, pois o suporte geral do navegador já é muito bom para a versão regular. Especialmente se você deseja digitalizar a partir da câmera do dispositivo, o suporte à câmera pelo navegador é a restrição mais rigorosa.
Crie um elemento <video>
onde o stream de vídeo da web cam deve ser renderizado:
< video > </ video >
// To enforce the use of the new api with detailed scan results, call the constructor with an options object, see below.
const qrScanner = new QrScanner (
videoElem ,
result => console . log ( 'decoded qr code:' , result ) ,
{ /* your options or returnDetailedScanResult: true if you're not specifying any other options */ } ,
) ;
// For backwards compatibility, omitting the options object will currently use the old api, returning scan results as
// simple strings. This old api will be removed in the next major release, by which point the options object is then
// also not required anymore to enable the new api.
const qrScanner = new QrScanner (
videoElem ,
result => console . log ( 'decoded qr code:' , result ) ,
// No options provided. This will use the old api and is deprecated in the current version until next major version.
) ;
Como terceiro parâmetro opcional, um objeto de opções pode ser fornecido. As opções suportadas são:
Opção | Descrição |
---|---|
onDecodeError | Manipulador a ser invocado em erros de decodificação. O padrão é QrScanner._onDecodeError . |
preferredCamera | Preferência pela câmera a ser usada. A preferência pode ser um ID de dispositivo retornado por listCameras ou um modo de face especificado como 'environment' ou 'user' . O padrão é 'environment' . Observe que não há garantia de que a preferência possa realmente ser atendida. |
maxScansPerSecond | Esta opção pode ser usada para acelerar as varreduras para reduzir o consumo de bateria. O padrão é 25. Se suportado pelo navegador, a taxa de varredura nunca será superior à taxa de quadros da câmera para evitar varreduras duplicadas desnecessárias no mesmo quadro. |
calculateScanRegion | Um método que determina uma região à qual a varredura deve ser restrita como uma melhoria de desempenho. Opcionalmente, essa região também pode ser reduzida antes de executar a verificação como uma melhoria adicional de desempenho. A região é especificada como x , y , width e height ; as dimensões da região reduzida como downScaledWidth e downScaledHeight . Observe que a proporção entre width e height e downScaledWidth e downScaledHeight deve permanecer a mesma. Por padrão, a região de varredura é restrita a um quadrado centralizado de dois terços da largura ou altura do vídeo, o que for menor, e reduzida para um quadrado de 400x400. |
highlightScanRegion | Defina esta opção como true para renderizar um contorno ao redor da região de varredura no fluxo de vídeo. Isso usa um div absolutamente posicionado que cobre a região de varredura. Esta div pode ser fornecida como opção overlay , veja abaixo, ou criada automaticamente e acessada via qrScanner.$overlay . Ele pode ser estilizado livremente via CSS, por exemplo, definindo um contorno, borda, cor de fundo, etc. Veja exemplos na demonstração. |
highlightCodeOutline | Defina esta opção como true para renderizar um contorno em torno dos códigos QR detectados. Isso usa um div absolutamente posicionado no qual um SVG para renderizar o contorno será colocado. Esta div pode ser fornecida como opção overlay , veja abaixo, ou ser acessada via qrScanner.$overlay . O SVG pode ser estilizado livremente via CSS, por exemplo, definindo a cor de preenchimento, cor do traço, largura do traço, etc. Veja exemplos na demonstração. Para necessidades mais especiais, você também pode usar cornerPoints diretamente, veja abaixo, para renderizar um contorno ou os pontos você mesmo. |
overlay | Um div personalizado que pode ser fornecido para uso em highlightScanRegion e highlightCodeOutline . O div deve ser irmão de videoElem no DOM. Se esta opção for fornecida, os estilos padrão para highlightCodeOutline não serão aplicados, pois a expectativa é que o elemento já tenha algum estilo personalizado aplicado a ele. |
returnDetailedScanResult | Aplique relatórios detalhados de resultados de verificação, veja abaixo. |
Para usar o valor padrão para uma opção, omita-o ou forneça undefined
.
Os resultados passados para o retorno de chamada dependem de um objeto de opções ter sido fornecido:
data
de propriedades que são o conteúdo da string do código QR lido e cornerPoints
que são os pontos de canto do contorno do código QR lido no fluxo da câmera. Para evitar o uso da API obsoleta se você não fornecer nenhuma outra opção, você pode fornecer { returnDetailedScanResult: true }
para ativar a nova API e obter o resultado detalhado da verificação.
qrScanner . start ( ) ;
Chame-o quando estiver pronto para digitalizar, por exemplo, ao clicar em um botão ou diretamente no carregamento da página. Ele solicitará permissão ao usuário para usar uma câmera. Nota: para ler um stream da Web Cam, sua página deve ser veiculada via HTTPS.
qrScanner . stop ( ) ;
Se desejar, você pode parar a varredura a qualquer momento e retomá-la chamando start()
novamente.
QrScanner . scanImage ( image )
. then ( result => console . log ( result ) )
. catch ( error => console . log ( error || 'No QR code found.' ) ) ;
As fontes de imagem suportadas são: HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, OffscreenCanvas, Arquivo/Blob, URIs de dados, URLs apontando para uma imagem (se estiverem na mesma origem ou habilitados para CORS)
Como segundo parâmetro opcional, um objeto de opções pode ser fornecido. As opções suportadas são:
Opção | Descrição |
---|---|
scanRegion | Uma região definida por x , y , width e height à qual a busca por um código QR deve ser restrita. Como uma melhoria de desempenho, esta região pode ser reduzida antes de realizar a verificação, fornecendo downScaledWidth e downScaledHeight . Observe que a proporção entre width e height e downScaledWidth e downScaledHeight deve permanecer a mesma. Por padrão, a região abrange toda a imagem e não é reduzida. |
qrEngine | Uma instância do mecanismo de scanner QR criada manualmente para ser reutilizada. Isso melhora o desempenho se você estiver digitalizando muitas imagens. Um mecanismo pode ser criado manualmente por meio de QrScanner.createQrEngine(QrScanner.WORKER_PATH) . Por padrão, nenhum mecanismo é reutilizado para digitalização de imagens únicas. |
canvas | Uma tela criada manualmente para ser reutilizada. Isso melhora o desempenho se você estiver digitalizando muitas imagens. Uma tela pode ser criada manualmente por meio de uma tag <canvas> em sua marcação ou document.createElement('canvas') . Por padrão, nenhuma tela é reutilizada para digitalização de imagens únicas. |
disallowCanvasResizing | Solicite que uma tela fornecida para reutilização não seja redimensionada, independentemente da imagem de origem ou das dimensões da região de origem. Observe que a tela e a região de origem devem ter a mesma proporção para evitar que a imagem a ser digitalizada fique distorcida, o que poderia impossibilitar a detecção de códigos QR. Por padrão, o tamanho da tela é adaptado às dimensões da região de digitalização ou à região de digitalização reduzida para digitalização de imagem única. |
alsoTryWithoutScanRegion | Solicite uma segunda varredura em toda a imagem se um scanRegion tiver sido fornecido e nenhum código QR for encontrado nessa região. Por padrão, nenhuma segunda varredura é tentada. |
returnDetailedScanResult | Aplique relatórios detalhados de resultados de verificação, veja abaixo. |
Para usar o valor padrão para uma opção, omita-o ou forneça undefined
.
Os resultados retornados dependem de um objeto de opções ter sido fornecido:
data
de propriedades que são o conteúdo da string do código QR lido e cornerPoints
que são os pontos de canto do contorno do código QR lido no fluxo da câmera. Para evitar o uso da API obsoleta se você não fornecer nenhuma outra opção, você pode fornecer { returnDetailedScanResult: true }
para ativar a nova API e obter o resultado detalhado da verificação.
Se nenhum código QR puder ser lido, scanImage
será lançado.
Esta biblioteca fornece um método utilitário para verificar se o dispositivo possui uma câmera. Isso pode ser útil para determinar se a funcionalidade de digitalização QR web cam deve ser oferecida a um usuário.
QrScanner . hasCamera ( ) ; // async
Esta biblioteca fornece um método utilitário para obter uma lista das câmeras do dispositivo, definidas por meio de seu id
e label
. Isso pode ser útil para permitir que um usuário escolha uma câmera específica para usar.
Opcionalmente, você pode solicitar as etiquetas da câmera. Observe que isso, entretanto, requer permissão do usuário para acessar as câmeras, que será solicitada a ele, caso ainda não tenha sido concedida. Se não for solicitado especificamente, os rótulos dos dispositivos serão determinados com base no melhor esforço, ou seja, os rótulos reais serão retornados se as permissões já tiverem sido concedidas e os rótulos alternativos caso contrário. Se você deseja solicitar rótulos de câmeras, é recomendável chamar listCameras
após uma instância do QrScanner ter sido iniciada com sucesso, pois a essa altura o usuário já terá dado sua permissão.
QrScanner . listCameras ( ) ; // async; without requesting camera labels
QrScanner . listCameras ( true ) ; // async; requesting camera labels, potentially asking the user for permission
Você pode alterar a câmera preferida a ser usada. A preferência pode ser um ID de dispositivo retornado por listCameras
ou um modo de face especificado como 'environment'
ou 'user'
. Observe que não há garantia de que a preferência possa realmente ser atendida.
qrScanner . setCamera ( facingModeOrDeviceId ) ; // async
O scanner, por padrão, procura códigos QR escuros em um fundo claro. Você pode alterar esse comportamento para procurar códigos QR brilhantes em fundo escuro ou ambos ao mesmo tempo:
qrScanner . setInversionMode ( inversionMode ) ;
Onde inversionMode
pode ser original
, invert
ou both
. O padrão para digitalização de webcam é original
e both
digitalização de imagem única.
Altere os pesos de vermelho, verde e azul no cálculo da escala de cinza para melhorar o contraste dos códigos QR de uma cor específica:
qrScanner . setGrayscaleWeights ( red , green , blue , useIntegerApproximation = true ) ;
Onde red
, green
e blue
devem somar 256 se useIntegerApproximation === true
e 1
caso contrário. Por padrão, esses valores são usados.
Em navegadores suportados, você pode verificar se a câmera usada atualmente possui flash e ligá-lo ou desligá-lo. Observe que hasFlash deve ser chamado após o scanner ter sido iniciado com sucesso para evitar a necessidade de abrir um fluxo de câmera temporário apenas para consultar se ele tem suporte a flash, potencialmente solicitando ao usuário acesso à câmera.
qrScanner . hasFlash ( ) ; // check whether the browser and used camera support turning the flash on; async.
qrScanner . isFlashOn ( ) ; // check whether the flash is on
qrScanner . turnFlashOn ( ) ; // turn the flash on if supported; async
qrScanner . turnFlashOff ( ) ; // turn the flash off if supported; async
qrScanner . toggleFlash ( ) ; // toggle the flash if supported; async.
Você pode destruir o scanner QR se não precisar mais dele:
qrScanner . destroy ( ) ;
qrScanner = null ;
Isso interromperá o fluxo da câmera e do web trabalhador e limpará os ouvintes de eventos. O scanner QR ficará disfuncional após ser destruído.
O projeto é pré-construído em qr-scanner.min.js em combinação com qr-scanner-worker.min.js. Construir você mesmo só é necessário se você quiser alterar o código na pasta /src. NodeJs é necessário para construção.
Instale os pacotes de compilação necessários:
yarn
Prédio:
yarn build