MostlyQR

¿Qué tan grande puede ser el logotipo en un código QR? Lo medimos

"Corrección de errores del 30%" no es un presupuesto de logotipo. Hicimos agujeros cada vez más grandes en códigos en cada nivel de EC hasta que un decodificador real se rindió, y registramos dónde se rompió.

Max Čelar··Impresión y escaneo

Novedades aquí: El parche centrado más grande que un código QR tolera en cada nivel de corrección de errores, medido perforando un agujero cada vez más grande en un símbolo real y decodificándolo con jsQR — 4% en L, 7% en M, 12% en Q, 17% en H — más dos resultados que nadie publica: el daño disperso rompe un código en 4% donde un blob contiguo sobrevive 17%, y el mismo parche sobre un patrón de búsqueda lo rompe en 1%.

Toda guía sobre cómo poner un logo en un código QR dice lo mismo: usar nivel de corrección de errores H y recordar que puede recuperar el 30% del código. La segunda parte se repite tan a menudo que se ha convertido en un brief de diseño — cubrir hasta el 30% — y eso no es lo que el número significa.

Fuimos y medimos qué es lo que realmente significa.

# Qué significa realmente la «corrección de errores del 30%»

Un código QR no almacena tus datos como píxeles de los que puedas perder algunos. Almacena palabras de código: bloques de ocho módulos, protegidos por corrección de errores Reed–Solomon. La cifra destacada del nivel H describe aproximadamente cuántas de esas palabras de código se pueden reconstruir — y parte de esa capacidad se consume por la sobrecarga de la propia codificación antes de que toques nada.

Dos consecuencias que importan más que el número:

  • El daño se cuenta por palabra de código, no por módulo. Arruinar un módulo arruina la palabra de código completa a la que pertenece.
  • Los patrones de búsqueda, patrones de temporización e información de formato no están cubiertos por corrección de errores en absoluto. Es cómo el decodificador encuentra el símbolo en primer lugar, y no hay nada para reconstruirlos.

Entonces «30%» es un hecho sobre las matemáticas y no un permiso sobre la imagen. Aquí está el permiso.

# El presupuesto de logo medido, por nivel

El método, para que puedas repetirlo: codifica https://mqr.sh/AB12CD con el codificador que MostlyQR proporciona (buildMatrix, envolviendo node-qrcode del MIT), fijado a la versión de símbolo 3 (29 módulos) en cada nivel de corrección de errores para que EC sea la única variable. Renderiza a 8 píxeles por módulo con la zona de silencio completa de 4 módulos. Blanquea un cuadrado centrado, comenzando con el 1% del área del símbolo e incrementándolo 1% cada vez, y pasa los píxeles a jsQR 1.4.0 después de cada paso. El número registrado es el último tamaño que se decodificó antes del primer fallo.

Corrección de errores Parche blanco centrado más grande que aún se decodificó
L 4% del área del símbolo
M 7%
Q 12%
H 17%

El nivel H vale aproximadamente cuatro veces el nivel L — una diferencia real, y la razón por la que toda guía te dice que lo uses. También está muy lejos del 30%.

Como regla general de estos números: en el nivel H, un logo centrado que ocupe aproximadamente 15% del área del código — un cuadrado aproximadamente del 39% del ancho del código — está dentro del límite medido con un poco de margen. El límite medido en el nivel M es 7%, que es un cuadrado de aproximadamente el 26% del ancho, así que reduce de la misma manera y bajas a aproximadamente una quinta parte.

Repetimos todo a 16 píxeles por módulo y obtuvimos resultados idénticos, que es el resultado esperado: esta es una propiedad del símbolo, no del renderizado.

# Por qué una mancha es más barata que confeti

Aquí está el resultado que no esperábamos, y es el que explica por qué los logos centrados funcionan en absoluto.

En lugar de un parche contiguo, volteamos módulos de datos individuales al azar en todo el símbolo — dejando intacto cada patrón de búsqueda, temporización y alineación — e incrementamos la tasa hasta que la decodificación falló. Mismo payload, misma versión, mismo decodificador, cinco semillas aleatorias diferentes:

Corrección de errores Daño disperso máximo (mediana de 5 ejecuciones)
L 1% de 567 módulos de datos
M 3%
Q 3%
H 4%

(El símbolo v3 tiene 841 módulos, de los cuales 567 contienen datos; el resto son patrones de búsqueda, temporización, alineación y formato, que esta prueba dejó intactos.)

Cuatro por ciento disperso, contra diecisiete por ciento en una mancha, en el mismo nivel.

La razón es la palabra de código. Un cuadrado contiguo del 17% arruina un pequeño número de palabras de código completamente. La misma cantidad de daño esparcido uniformemente arruina una parte de muchas palabras de código — y una palabra de código con un módulo malo está exactamente tan rota como una palabra de código con ocho. La corrección de errores cuenta víctimas, no daño.

Lo cual invierte el instinto habitual. Una sola forma limpia en un lugar es la forma más barata de gastar tu corrección de errores. Las pecas, una textura, una marca de agua semi-transparente o un filtro de fotos en todo el código es lo más costoso, incluso cuando parece menos daño.

# Los tres rincones que no debes cubrir

Misma prueba, mismo cuadrado creciente, movido a otras dos posiciones:

Posición del parche Punto de ruptura del nivel H
centro 17%
esquina inferior derecha (sobre el patrón de alineación) 5%
esquina superior izquierda (sobre el patrón de búsqueda) 1%

En el nivel L, el caso superior izquierdo falló en el primer paso — menos del 1%.

Esas esquinas son estructura, no contenido. Los tres cuadrados concéntricos grandes son los patrones de búsqueda, y el más pequeño en el interior cerca de la esquina inferior derecha es un patrón de alineación; entre ellos el decodificador calcula dónde está el símbolo, cuán grande es y cómo está rotado o sesgado. Cubre uno y no hay paso de decodificación al que llegar. El nivel de corrección de errores hace casi ninguna diferencia, porque la corrección de errores nunca los protegió.

Por eso el lugar seguro para un logo es el medio, y por qué «simplemente hazlo más pequeño y colócalo en una esquina» es precisamente al revés.

# Qué agrega una cámara que esta prueba no

Todo lo anterior es un caso limpio, sintético, mejor caso:

  • Un decodificador. jsQR es un buen decodificador ampliamente utilizado, pero la pila de cámara de un teléfono no es jsQR. Los lectores reales varían en cuán agresivamente intentan un código dañado.
  • Píxeles perfectos. Sin desenfoque, sin destello, sin perspectiva, sin impresión. Cada uno de esos reduce el presupuesto.
  • Un agujero blanco limpio. Un logo real tiene color, bordes y suavizado contra los módulos debajo. La placa blanca detrás de un logo no es decoración — es lo que hace que el área cubierta sea inequívoca.

Trata la tabla como un límite superior medido en condiciones ideales, no como un objetivo para diseñar. Nuestro propio consejo es gastar aproximadamente dos tercios de ella.

# Ejecutar esto tú mismo

Cada número anterior se imprime mediante un script en lugar de escribirse en el artículo: draft/mostlyqr/seo/benchmarks/logo.js en nuestro repositorio. Renderiza el símbolo en cada nivel, hace crecer cada parche un porcentaje a la vez, ejecuta la comparación de daño disperso en cinco semillas, y reejecuta todo a una segunda escala de píxeles. También sondea nuestro propio validador para el límite citado al final de esta pieza.

# Qué hacer realmente

  1. Usa nivel de corrección de errores H cuando hay un logo. Aproximadamente cuadruplica tu presupuesto, y cuesta aproximadamente cuatro módulos extras por lado en un enlace corto — que es una decisión de tamaño que puedes calcular en lugar de adivinar.
  2. Mantén el logo centrado, y mantenlo bajo aproximadamente 15% del área del código. Eso es un cuadrado aproximadamente del 39% del ancho del código, en el nivel H.
  3. Colócalo en una placa sólida, para que el área cubierta sea clara en lugar de ambigua.
  4. Nunca dejes que nada toque los tres cuadrados de las esquinas — no el logo, no un marco, no un recorte de esquina redondeada.
  5. Prueba la impresión real con un teléfono malo. Cada número aquí dice qué diseños vale la pena probar. Solo la prueba dice si funciona.

Si quieres que la imagen sea todo el código en lugar de un parche en el medio, esa es una técnica diferente con un presupuesto diferente — medimos códigos QR fotográficos por separado, y resulta que no gastan corrección de errores en absoluto. Y si solo quieres un código con tu logo, el generador de MostlyQR fuerza la corrección de errores hasta el nivel H en el momento en que se añade un logo, mantiene la zona de silencio de 4 módulos, y establece el logo por defecto al 22% del ancho del código — 4.8% de su área, cómodamente dentro de todo lo medido anteriormente.

Una nota honesta sobre nuestro propio código, ya que estamos publicando los números: el guarda que rechaza un logo demasiado grande usa la cifra nominal de recuperación del 30% con un corte del 15%, por lo que aceptará un logo que cubre aproximadamente el 25% del área en el nivel H. Nuestra medición dice que el techo real es más cercano al 17%. El valor predeterminado que nadie cambia es seguro por un gran margen, pero el límite es más laxo que lo que la evidencia respalda, y eso es un error en nuestro validador en lugar de una sutileza de los códigos QR, y está en la lista de arreglos.

Preguntas frecuentes

¿Puede un logotipo cubrir el 30% de un código QR?

No. El "30%" en el nivel de corrección de errores H se refiere a palabras de código — bloques de ocho módulos que Reed-Solomon puede reconstruir — y parte de ese presupuesto ya se ha gastado en la codificación en sí, no se mantiene en reserva para usted. En nuestra prueba, el cuadrado centrado más grande que pudimos blanquear de un código de nivel H y aún decodificar fue el 17% del área del símbolo. En el nivel L fue el 4%. Trata el 30% como una descripción de las matemáticas, no como una asignación de diseño.

¿Qué nivel de corrección de errores debo usar para un código QR con un logotipo?

H, si puedes permitirte el tamaño. En nuestra medición más o menos cuadruplicó el parche tolerable centrado en comparación con el nivel L (17% contra 4%) al costo de cuatro módulos extra por lado en un enlace corto. La única salvedad es que la corrección de errores y un tamaño de impresión pequeño compiten por el mismo presupuesto — un código de nivel H con un logotipo necesita ser impreso más grande, no más pequeño.

¿Por qué mi código QR deja de funcionar cuando cubro una esquina?

Porque las esquinas no son datos. Los tres cuadrados grandes son patrones de búsqueda, el cuadrado más pequeño cerca de la esquina inferior derecha es un patrón de alineación, y ambos son cómo un lector localiza y cuadra el símbolo antes de decodificar nada. No están protegidos por corrección de errores — no hay nada de lo que reconstruirlos. En nuestra prueba un parche sobre un patrón de búsqueda rompió la decodificación en el 1% del área del símbolo, contra el 17% en el medio.

¿Necesita un logotipo en un código QR un borde blanco?

En la práctica sí, y nuestros números asumen uno. Probamos blanqueando un cuadrado, que es el mejor caso: un agujero limpio y de alto contraste con bordes afilados que el decodificador puede tratar como uniformemente claro. Un logotipo colocado directamente sobre los módulos sin una placa detrás produce módulos ambiguos medio oscuros alrededor de su borde, que cuesta más que la misma área de blanco limpio.

Fuentes
  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
Más en este tema