MostlyQR

Jak velké smí být logo na QR kódu? Změřili jsme to

„30%“ korekce chyb není rozpočet na logo. Vyráželi jsme do kódů díry, dokud skutečný dekodér nevzdal, a zapsali jsme, kde se to zlomilo.

Max Čelar··Tisk a skenování

Co je tu nového: Největší středová plocha, kterou QR kód na každé úrovni korekce chyb tolerovat, změřená vyražením rostoucí díry do skutečného symbolu a jeho dekódováním pomocí jsQR: 4% na L, 7% na M, 12% na Q, 17% na H. Dále dva výsledky, které nikdo nezveřejňuje: rozptýlené poškození rozbije kód už při 4%, kdežto jedna souvislá skvrna přežije 17%, a stejná plocha přes vyhledávací vzor (finder pattern) ho rozbije už při 1%.

Každý návod, jak dát logo na QR kód, říká dvě věci: použij úroveň korekce chyb H a pamatuj, že kód dokáže obnovit 30 % svého obsahu. Ta druhá půlka se opakuje tak často, že se z ní stalo designové zadání — zakryj až 30 % — a to není to, co to číslo znamená.

Změřili jsme, co to doopravdy znamená.

# Co ve skutečnosti znamená „30% korekce chyb"

QR kód neukládá data jako pixely, z nichž můžeš pár ztratit. Ukládá kódová slova: bloky osmi modulů, chráněné Reed–Solomonovým kódem pro korekci chyb. Hlavní číslo úrovně H popisuje přibližně to, kolik z těchto kódových slov lze rekonstruovat — a část kapacity je spotřebována režií samotného kódování dřív, než na kód vůbec sáhneš.

Dva důsledky, které jsou důležitější než samotné číslo:

  • Poškození se počítá na kódové slovo, ne na modul. Pokažení jednoho modulu zničí celé kódové slovo, do kterého patří.
  • Finder vzory, timing vzory a informace o formátu korekcí chyb vůbec nejsou kryty. Slouží k tomu, aby dekodér symbol vůbec našel, a není z čeho je rekonstruovat.

Takže „30 %" je fakt o matematice, a ne povolení k tomu, co je na obrázku. Tady je povolení, které hledáš.

# Změřený rozpočet loga podle úrovně

Postup, abys ho mohl zopakovat: zakóduj https://mqr.sh/AB12CD pomocí enkodéru, který MostlyQR dodává (buildMatrix, obalující MIT knihovnu node-qrcode), připnutý na verzi symbolu 3 (29 modulů) u každé úrovně korekce chyb, aby byla korekce chyb jediná proměnná. Vykresli na 8 pixelů na modul s plnou 4modulovou tichou zónou. Vybílej středový čtverec, začni na 1 % plochy symbolu a zvětšuj o 1 % krok za krokem, a pixely po každém kroku předej jsQR 1.4.0. Zaznamenané číslo je poslední velikost, která se ještě dekódovala, než nastalo první selhání.

Korekce chyb Největší středová bílá plocha, která se stále dekódovala
L 4% plochy symbolu
M 7%
Q 12%
H 17%

Úroveň H je zhruba čtyřikrát tolik co L — skutečný rozdíl a důvod, proč ti každý návod radí ji použít. Ale ani zdaleka se nedostane na 30 %.

Jako pravidlo palce z těchto čísel: u úrovně H se středové logo zabírající zhruba 15 % plochy kódu — čtverec zhruba 39 % šířky kódu — vejde do změřeného limitu s malou rezervou. Změřený limit u úrovně M je 7 %, což je čtverec asi 26 % šířky, takže ho zkrať stejným způsobem a dostaneš se zhruba na pětinu.

Celé to jsme znovu spustili při 16 pixelech na modul a dostali identické výsledky, což je očekávaný výsledek: jde o vlastnost symbolu, ne o vykreslování.

# Proč je skvrna levnější než konfety

Tady je výsledek, který jsme nečekali, a ten vysvětluje, proč středová loga vůbec fungují.

Místo jednoho souvislého výřezu jsme náhodně převraceli jednotlivé datové moduly po celém symbolu — finder, timing a alignment vzory jsme nechali nedotčené — a zvyšovali míru, dokud dekódování nezkolabovalo. Stejná data, stejná verze, stejný dekodér, pět různých náhodných semen:

Korekce chyb Maximální rozptýlené poškození (medián z 5 běhů)
L 1 % z 567 datových modulů
M 3 %
Q 3 %
H 4 %

(Symbol v3 má 841 modulů, z nichž 567 nese data; zbytek tvoří finder, timing, alignment a formátovací vzory, které test nechal být.)

Čtyři procenta rozptýlené, proti sedmnácti procentům v jedné skvrně, při téže úrovni.

Důvod je kódové slovo. Souvislý čtverec 17 % zničí malý počet kódových slov úplně. Stejné množství poškození rozprášené rovnoměrně zničí kus mnoha kódových slov — a kódové slovo s jedním špatným modulem je přesně tak rozbité jako kódové slovo s osmi. Korekce chyb počítá oběti, ne poškození.

To obrací běžný instinkt. Jediný čistý tvar na jednom místě je nejlevnější způsob, jak utratit svou korekci chyb. Cákance, textura, poloprůhledný vodoznak nebo fotografický filtr přes celý kód jsou nejdražší, i když to vypadá jako menší poškození.

# Tři rohy, které nesmíš zakrýt

Stejný test, stejný rostoucí čtverec, přesunutý na dvě další pozice:

Pozice výřezu Bod zlomu u úrovně H
střed 17%
pravý dolní roh (přes alignment vzor) 5%
levý horní roh (přes finder vzor) 1%

U úrovně L selhal levý horní případ hned při prvním kroku — pod 1 %.

Tyto rohy jsou struktura, ne obsah. Tři velké soustředné čtverce jsou finder vzory a menší, zanořený blízko pravého dolního rohu je alignment vzor; mezi nimi dekodér zjistí, kde symbol je, jak velký je a jak je otočený nebo zkosený. Zakryješ-li jeden z nich, do dalšího kroku dekódování se nedostane. Úroveň korekce chyb téměř nic nemění, protože korekce chyb je nikdy nechránila.

Proto je bezpečné místo pro logo střed a proto je „prostě ho zmenši a dej do rohu" přesně obráceně.

# Co přidá kamera, co tento test neukazuje

Všechno výše je čistý, syntetický nejlepší případ:

  • Jeden dekodér. jsQR je dobrý a široce používaný dekodér, ale kamerový systém telefonu není jsQR. Skutečné čtečky se liší v tom, jak agresivně se pokoušejí o poškozený kód.
  • Dokonalé pixely. Žádné rozmazání, odlesky, perspektiva ani tisk. Každé z toho rozpočet zmenšuje.
  • Čistý bílý otvor. Skutečné logo má barvy, hrany a vyhlazování proti modulům pod ním. Bílá podložka za logem není dekorace — je to to, co zajišťuje, že zakrytá plocha je jednoznačná.

Tabulku ber jako horní mez změřenou za ideálních podmínek, ne jako cíl, ke kterému navrhuj. Naše vlastní rada je využít zhruba dvě třetiny z ní.

# Vyzkoušej si to sám

Každé číslo výše vypisuje skript, a ne je přepsané ručně do článku: draft/mostlyqr/seo/benchmarks/logo.js v našem repozitáři. Vykreslí symbol na každé úrovni, zvětšuje každou plochu po procentech, spustí srovnání rozptýleného poškození přes pět semen a celé to znovu spustí v druhém měřítku pixelů. Také otestuje náš vlastní validátor na hranici citovanou na konci článku.

# Co teď skutečně udělat

  1. Použij úroveň korekce chyb H, když máš logo. Zhruba čtyřnásobně zvětší tvůj rozpočet a na krátkém odkazu stojí přibližně čtyři extra moduly na stranu — což je rozhodnutí o velikosti, které si můžeš spočítat, místo abys hádal.
  2. Nech logo uprostřed a drž ho pod zhruba 15 % plochy kódu. To je čtverec zhruba 39 % šířky kódu na úrovni H.
  3. Dej ho na plnou podložku, aby zakrytá plocha byla čistá, a ne nejednoznačná.
  4. Nikdy nenech nic dotknout se tří rohových čtverců — ani logo, ani rámeček, ani oříznutí se zaoblenými rohy.
  5. Otestuj skutečný tisk s horším telefonem. Všechna čísla zde říkají, které návrhy stojí za test. Jen test říká, zda to funguje.

Pokud chceš, aby byl obrázek celým kódem a ne záplatou uprostřed, je to jiná technika s jiným rozpočtem — fotografické QR kódy jsme změřili zvlášť a ukázalo se, že žádnou korekci chyb nespotřebují. A pokud chceš jen kód s tvým logem, generátor MostlyQR zvedne korekci chyb na úroveň H ve chvíli, kdy přidáš logo, zachová 4modulovou tichou zónu a logo ve výchozím nastavení nastaví na 22 % šířky kódu — 4.8 % jeho plochy, bezpečně uvnitř všeho, co jsme změřili výše.

Jedna upřímná poznámka k našemu vlastnímu kódu, protože čísla publikujeme: ochrana, která odmítá příliš velké logo, používá nominální 30% údaj o obnově se 15% srážkou, takže přijme logo zakrývající zhruba 25 % plochy na úrovni H. Naše měření říká, že skutečný strop je spíš 17 %. Výchozí nastavení, které nikdo nemění, je bezpečné s velkou rezervou, ale limit je volnější, než důkazy podporují, a to je chyba v našem validátoru, ne jemnost QR kódů, a je na seznamu oprav.

Často kladené otázky

Může logo zakrýt 30% QR kódu?

Ne. „30%“ u úrovně korekce chyb H se vztahuje na kódová slova, tedy bloky osmi modulů, které Reed-Solomon dokáže rekonstruovat. Část tohoto rozpočtu je už spotřebována samotným kódováním, takže není k dispozici jako rezerva pro tebe. V našem testu byl největší středový čtverec, který jsme u kódu úrovně H mohli zabělit a který se stále dekódoval, 17% plochy symbolu. U úrovně L to bylo 4%. Ber 30% jako popis matematiky, ne jako návrhový příděl.

Kterou úroveň korekce chyb použít u QR kódu s logem?

H, pokud si to můžeš dovolit velikostně. Podle našeho měření se tolerovaná středová plocha oproti úrovni L přibližně zčtyřnásobila (17% oproti 4%) za cenu čtyř dalších modulů na každou stranu u krátkého odkazu. Jedna výhrada: korekce chyb a malá tištěná velikost soutěží o stejný rozpočet. Kód úrovně H s logem je třeba tisknout větší, ne menší.

Proč přestane můj QR kód fungovat, když zakryji roh?

Protože rohy nejsou data. Tři velké čtverce jsou vyhledávací vzory (finder patterns), menší čtverec blízko pravého dolního rohu je zarovnávací vzor (alignment pattern) a oba slouží tomu, aby čtečka symbol našla a narovnala dřív, než cokoli dekóduje. Korekce chyb je nechrání, protože není z čeho je rekonstruovat. V našem testu rozbila dekódování skvrna přes vyhledávací vzor už při 1% plochy symbolu, oproti 17% uprostřed.

Potřebuje logo na QR kódu bílý okraj?

V praxi ano a naše čísla s ním počítají. Testovali jsme zabělením čtverce, což je nejlepší případ: čistá, kontrastní díra s ostrými hranami, kterou dekodér může považovat za rovnoměrně světlou. Logo položené přímo na moduly bez podložky vytváří na okraji nejednoznačné napůl tmavé moduly, a ty stojí víc než stejná plocha čistého bílého.

Zdroje
  1. jsQR — the decoder used in the test
  2. node-qrcode (the MIT encoder our matrix builder wraps)
  3. QR Code standardization (ISO/IEC 18004) — Denso Wave
Další v tomto tématu