SWAPQR← Guida

Perché un codice QR artistico può fallire se lo scansioni troppo da vicino

Tutti si aspettano che un codice QR fallisca perché è troppo piccolo, troppo lontano, troppo poco illuminato. I codici QR fotografici hanno anche il fallimento opposto: possono leggersi perfettamente da lontano e fallire quando avvicini il telefono fino a toccarli. Ecco perché, con i numeri della misurazione che lo ha scoperto.

Crea un codice QR nel browser →Stampa il quadrato una volta sola. Decidi dopo dove porta.

Come uno scanner decide cosa è scuro

Prima che un lettore possa cercare i moduli, deve trasformare una fotografia in bianco e nero. Una soglia globale non sopravvive all'illuminazione reale — un'ombra su un angolo annerirebbe metà del codice — quindi la maggior parte dei decodificatori applica la soglia localmente. ZXing, la libreria open source da cui discende ancora gran parte della scansione di codici a barre, divide l'immagine in blocchi di 8×8 pixel, calcola la media di ogni blocco, la smussa rispetto ai blocchi vicini, e la usa come soglia per quei 64 pixel. Un pixel più scuro della soglia del suo blocco è scuro; gli altri sono chiari. Per un codice QR normale questo è praticamente gratis. Qualunque sia la dimensione del blocco, un modulo è pieno, quindi la media di un blocco è o vicina allo scuro o vicina al chiaro, o sta tra i due quando il blocco è a cavallo di un confine, e la decisione è facile in ogni caso. Lo schema è robusto, economico ed è stato copiato ampiamente, ed è esattamente per questo che conta: il decodificatore che il tuo codice stampato incontra sul campo potrebbe benissimo essere uno che applica la soglia in questo modo.

Cosa cambia quando i moduli sono fatti di dithering

In un codice con dithering, un modulo non è pieno. È un piccolo nucleo forzato circondato da pixel che portano la fotografia. La sua media è corretta; la sua texture non è uniforme. Ora considera la distanza di scansione nell'unica unità che conta: pixel della fotocamera per modulo. Tieni il telefono abbastanza lontano che un modulo cada su 5–8 pixel, e un blocco 8×8 è a cavallo dei confini tra moduli. La media locale è più o meno "questo modulo e i suoi vicini", la soglia sta tra scuro e chiaro, e il codice si legge. Avvicina il telefono così che un modulo copra 20 pixel, e un blocco 8×8 ora sta interamente dentro un singolo modulo. La media del blocco è la texture locale di quel modulo. La soglia segue il dithering invece del modulo — e il decodificatore recupera i puntini, non il codice. Nulla della stampa è cambiato; solo il numero di pixel del sensore che ogni modulo copre, e con esso la relazione tra il blocco del decodificatore e il modulo. Ecco perché il fallimento è una proprietà della distanza piuttosto che della dimensione o dell'illuminazione.

Il numero

L'abbiamo misurato costruendo la modalità foto di SWAPQR: tre lunghezze di contenuto, sei tipi di immagine, entrambe le polarità di colore, tre impostazioni di bilanciamento, sette distanze di scansione simulate, decodificate da due librerie indipendenti. Il confine è netto. Con circa il 20% di ogni modulo forzato — l'impostazione orientata alla foto — e con circa il 44% forzato, i codici si leggevano a 5–8 pixel per modulo e i lettori di classe ZXing diventavano inaffidabili da vicino, a 10–28 pixel per modulo. A circa il 60% forzato e oltre, si leggevano a ogni distanza. Una volta che più di circa metà dell'area di un modulo è forzata piena, qualsiasi blocco 8×8 che cade dentro il modulo atterra per lo più su pixel pieni, e l'effetto scompare. Sotto quella soglia, non scompare — e nessuna regolazione del bias tonale lo risolve, perché una soglia locale sottrae comunque la media locale. Verso qualunque tono tu spinga un modulo, un blocco interamente dentro di esso misurerà quella tendenza come sua linea di base e la eliminerà con la soglia. L'unica leva che funziona è la quota del modulo che è piena, ed è per questo che esiste il controllo di bilanciamento.

Decodificatori più recenti, e perché non è la fine della storia

I decodificatori più recenti sono migliori in questo. Nella stessa serie di test, jsQR — che usa una strategia di binarizzazione diversa — ha letto ogni configurazione a ogni distanza, e gli scanner integrati nei telefoni attuali sono ancora più forti. Ma "la maggior parte dei telefoni ce la farà" non è la stessa cosa di "ogni lettore ce la farà", e un codice stampato incontra qualunque lettore gli venga puntato contro: un telefono più vecchio, uno scanner da punto vendita, un chiosco, un'app che incorpora una libreria derivata da ZXing. Il bilanciamento orientato alla foto è quindi onesto sul suo compromesso — lo studio nota che gli scanner dei telefoni moderni lo leggono a qualsiasi distanza mentre i lettori più vecchi e semplici possono avere difficoltà in primissimo piano estremo — e la decisione su dove collocarsi nel bilanciamento dipende da chi scansionerà il codice e da quanto lontano. Dipende anche da dove un telefono finisce naturalmente: nessuno tiene un telefono a distanza di braccio da un manifesto, ma tutti lo avvicinano fino a toccare un biglietto da visita, ed è quello il caso in cui un codice orientato alla foto e un lettore più semplice possono incontrarsi.

Cosa fare al riguardo

Se il codice va da qualche parte dove le persone scansionano da una distanza normale — un manifesto, un cavalletto da tavolo, un'etichetta da scaffale — le impostazioni orientate alla foto vanno bene; a quella distanza un modulo copre una manciata di pixel della fotocamera e i blocchi sono a cavallo dei confini come dovrebbero. Se va da qualche parte dove le persone appoggeranno un telefono contro di esso — un piccolo adesivo, un biglietto da visita, uno schermo — sposta il bilanciamento verso Codice, così che più di metà di ogni modulo sia piena e l'effetto da vicino scompaia per ogni classe di lettore. In ogni caso, stampane uno e scansionalo con un telefono. Non uno screenshot su un monitor: il pezzo stampato reale, alla dimensione reale, dalla distanza che le persone useranno davvero, e idealmente con più di un telefono. SWAPQR mostra questo avviso nello studio stesso anziché nelle note a piè di pagina, perché un codice che fallisce sul campo è peggio di un codice semplice che funziona, e perché la soluzione è un cursore anziché una ristampa se te ne accorgi prima della tiratura.

Quota forzata di ogni moduloLontano / normale (5–8 px per modulo)Da vicino (10–28 px per modulo)
~20% (orientato alla foto)Si leggeLettori di classe ZXing inaffidabili
~44% (medio)Si leggeLettori di classe ZXing inaffidabili
~60% e oltre (orientato al codice)Si leggeSi legge
Qualsiasi impostazione, lettori di classe jsQR e scanner dei telefoni attualiSi leggeSi legge nella stessa serie di test

Domande frequenti

Il mio telefono legge il codice fotografico da qualsiasi distanza. Perché l'avviso?

Gli scanner dei telefoni attuali usano una binarizzazione più forte e hanno letto ogni configurazione nella nostra serie di test. L'avviso riguarda i lettori più vecchi o semplici che applicano la soglia in blocchi 8×8, che un codice stampato può ancora incontrare.

Perché allontanare il telefono risolve il problema?

Più lontano, ogni modulo copre meno pixel della fotocamera, quindi il blocco 8×8 di un decodificatore è a cavallo di più moduli e la sua media sta tra scuro e chiaro. Da vicino, un blocco cade dentro un solo modulo e segue invece la texture del dithering.

Aumentare il bias tonale aiuta da vicino?

No. Una soglia locale sottrae la media locale, quindi qualsiasi tendenza uniforme dentro un modulo viene eliminata dalla soglia. Solo la quota del modulo che è forzata piena cambia il risultato.

Quale bilanciamento è sicuro per un biglietto da visita?

Spostalo verso Codice, così che più di circa metà di ogni modulo sia piena. A quel punto i lettori di classe ZXing leggono a ogni distanza nella nostra misurazione, e l'immagine è ancora visibile, solo più tenue.

Stampa il quadrato una volta sola. Decidi dopo dove porta. SWAPQR crea codici QR statici gratis, con tutte le opzioni di stile, senza account e senza filigrana. Un piano a pagamento rende un codice dinamico: il quadrato stampato resta identico mentre tu ne cambi la destinazione, e vedi quante volte è stato scansionato, per giorno e per dispositivo.

Crea un codice QR nel browser
Lingua: TR EN DE ES FR IT PT AR RU JA KO