Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

qrpix-logo

QR Code de Pix em SVG com a sua marca no meio, sem quebrar a leitura no app do banco.

Por que eu fiz isso

Eu queria pôr a logo do meu produto no meio do QR do Pix. Parece a coisa mais simples do mundo: gera o QR, joga a imagem em cima, acabou.

Aí o código para de ler.

Passei mais tempo do que eu gostaria de admitir mexendo nisso no olho. Diminuía o furo e testava, o app não abria. Aumentava a imagem, ficava bonito e parava de funcionar de novo. Troquei de gerador achando que era ele. Em lugar nenhum estava escrito o que de fato importa.

Quando finalmente funcionou, entendi que não era uma coisa só: eram quatro decisões, e dava para errar cada uma sozinha. Tirei essa parte do meu código, escrevi o porquê de cada uma junto e deixei aqui, pra próxima pessoa não gastar o tempo que eu gastei.

Usando

npm install qrpix-logo
import { qrPix } from "qrpix-logo";

const svg = qrPix(copiaECola, {
  tamanho: 320,
  logo: '<svg viewBox="0 0 100 100">...</svg>',
});

Sai uma string de SVG. Você joga no seu HTML e pronto. Não depende de navegador, então roda no servidor também.

As quatro decisões

1. Correção de erro H

O QR é gerado no nível H, que reconstrói 30% do código. É esse orçamento que paga o buraco da logo.

Com M, que reconstrói 15%, o mesmo furo derruba a leitura em parte dos leitores. E "parte dos leitores" é o pior tipo de bug que existe: funciona no seu celular e falha no do cliente, e você não fica sabendo.

O preço é densidade. Um BR Code de 170 caracteres vira uma matriz 65×65 em H contra 49×49 em M. Mais módulos no mesmo espaço quer dizer cada módulo menor.

2. O furo é redondo

Um furo quadrado no meio de módulos pequenos vira uma reta crua, e o olho lê como imagem cortada em vez de parte do desenho. Redondo, a borda acompanha a logo e some.

3. A limpeza é por interseção, não pelo centro do módulo

Essa foi a que mais me irritou, porque eu não conseguia enxergar o que estava errado.

Se você tira só os módulos cujo centro cai dentro do círculo, os que ficam na borda continuam desenhados, e o disco branco corta um pedaço de cada um. Sobra um anel de lascas em volta da logo. No tamanho normal quase não dá pra notar. Ampliando, é a única coisa que você vê.

O módulo tem que sair inteiro se encostar no círculo. Tem teste pra isso: mede a distância de cada módulo desenhado até a borda do disco e exige folga positiva.

4. A cor não vem do tema

Essa me custou mais caro que as outras três juntas.

Se você desenhar os módulos com uma variável CSS de tema (var(--text-primary) e parentes), o QR some no modo escuro: o token vira quase branco e o fundo do código continua branco. Eu medi 16,60:1 de contraste no claro contra 1,11:1 no escuro. A página abre normal, o SVG está inteiro lá, e o que aparece é um retângulo branco.

Inverter no escuro parece a saída. Não é. QR é escuro sobre claro por especificação, e parte dos leitores recusa o invertido. Numa tela de pagamento isso não se aposta, então o código fica igual nos dois temas, que é o que todo app de banco faz.

Dá pra trocar as cores por opção, mas a escura tem que ser a dos módulos.

Tamanho

pixelsPorModulo() responde antes de renderizar:

pixelsPorModulo(copiaECola, 300); // 4.35 num BR Code de 170 chars

Abaixo de uns 4 px por módulo a leitura começa a depender da câmera e da luz. Como a matriz cresce junto com o tamanho do BR Code, o mesmo tamanho em pixels não serve para toda cobrança.

Testando no banco de verdade

Teste passar não prova que o banco lê. O único jeito é escanear.

O truque que torna isso de graça: use o copia-e-cola de uma cobrança já paga. O app decodifica primeiro e valida depois, então ele abre e avisa que a cobrança não vale mais. Se ele disse isso, ele leu, e nenhum centavo saiu.

npm run exemplo -- "00020126580014BR.GOV.BCB.PIX..."

Escreve um escaneia.html com o seu QR e um sem logo do lado. Se o sem logo lê e o com logo não, o problema é o desenho. Se nenhum dos dois lê, o problema está no BR Code e não na estética.

API

qrPix(copiaECola, opcoes?)

opção padrão o que faz
tamanho 320 lado do SVG em px
logo (nenhum) SVG com viewBox="0 0 100 100". Sem ele não abre furo nenhum
tinta #111111 cor dos módulos, tem que ser a escura
papel #ffffff cor do fundo
furo 0.115 raio da área limpa, como fração do lado

Lança se o copia-e-cola vier vazio. Não valida o BR Code: validar é problema de quem gera a cobrança.

matriz(texto)

Devolve { tamanho, linhas } com as linhas em "0" e "1", se você quiser desenhar de outro jeito.

pixelsPorModulo(copiaECola, tamanho?)

Quantos pixels sobram por módulo naquele tamanho.

O que não faz

Não gera o BR Code, recebe pronto de quem emite a cobrança. Não valida CRC nem os campos do EMV. Não gera PNG, se precisar renderize o SVG.

Licença

MIT

About

QR Code de Pix em SVG com a sua marca no meio, sem quebrar a leitura no app do banco.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages