Blog

Codici a barre GS1-128 con precisione di 0,1 mm in JSON: guida pratica

GS1-128 sembra semplice finché lo scanner smette di leggere a 240 dpi. Guida pragmatica a lunghezza totale, X-dimension, quiet zone e perché HTML/CSS rende tutto più difficile.

Se spedite prodotti fisici, prima o poi dovrete stampare un codice a barre GS1-128 che uno scanner portatile reale deve leggere con la luce reale di un magazzino, a una distanza reale. Sembra noioso. In realtà è una delle cause di errore più rumorose nella generazione di PDF.

Questo articolo spiega che cosa significa davvero “precisione di 0,1 mm” per un codice GS1-128, perché i motori basati su HTML/CSS faticano a garantirla e quali poche regole progettuali fanno stampare correttamente il codice al primo tentativo su scanner DHL, FedEx, USPS e Amazon inbound.

Che cosa significa davvero “precisione del codice a barre”

GS1-128 (prima UCC/EAN-128) codifica i dati usando larghezze di barre e spazi con rapporti molto precisi. L’unità atomica è la X-dimension: la larghezza della barra o dello spazio più stretto. Tutto il resto è un multiplo di X (1X, 2X, 3X, 4X nei pattern interni di Code 128).

Gli scanner decodificano misurando larghezze relative. Se le larghezze stampate si spostano, la decodifica fallisce.

I due errori più comuni in produzione:

  1. X-dimension incoerente lungo il simbolo: il motore applica arrotondamenti sub-pixel diversi tra barre adiacenti. Le prime tre barre sono da 8 px, poi al centro compare una barra da 7 px. Lo scanner vede un pattern incoerente.
  2. Lunghezza totale o scala errata: il motore ha scalato il simbolo dopo il rendering, deformando la X-dimension sotto il minimo GS1 (di solito 0,495 mm a fattore di ingrandimento 1,0x).

Entrambi producono lo stesso sintomo: lo scanner emette un beep su un campione singolo, ma su un lotto di produzione compare un rifiuto ogni trenta. Non lo intercettate in QA perché lo scanner di sviluppo è più tollerante di quello usato in magazzino.

La regola degli 0,1 mm

La precisione rilevante è la lunghezza totale del codice a barre entro una tolleranza di 0,1 mm rispetto al target della specifica. NON significa “ogni barra è larga 0,1 mm”: le barre sono in genere da 0,495 mm o più. Il limite di 0,1 mm riguarda la precisione dimensionale cumulativa dell’intero simbolo.

Per un GS1-128 tipico con 18 caratteri numerici:

  • Il simbolo contiene circa 120 barre e spazi
  • Lunghezza totale a ingrandimento 1,0x: circa 58 mm
  • Tolleranza complessiva di 0,1 mm = circa 0,17% di accuratezza sull’intera lunghezza
  • Il budget di coerenza per barra è circa 0,001 mm, molto sotto la larghezza di una singola barra

Ecco perché “il motore disegna una barra da 7 px dove dovrebbe essere 7,4 px” è fatale. Gli arrotondamenti sub-pixel si sommano su 120 barre e la tolleranza di 0,1 mm salta da qualche parte tra la barra 50 e la barra 80.

Perché HTML/CSS fatica

Il percorso in cui inciampano molti team è questo: codificare i dati GS1-128 in una stringa, generare un SVG (o peggio, singole barre <div>), incorporarlo in HTML e renderizzare il PDF con Puppeteer o Prince.

Ogni anello della catena introduce deriva.

1. Il browser arrotonda la rasterizzazione

Anche SVG dentro HTML subisce arrotondamenti sub-pixel dal painter del browser, a meno che shape-rendering="crispEdges" sia impostato, il contenitore cada su un confine di pixel intero e i DPI del PDF moltiplichino in modo pulito le larghezze delle barre. Tre vincoli, tutti facili da violare per sbaglio.

2. Il layout CSS sposta le misure

Un transform: scale(0.95) da qualche parte nel foglio di stile, aggiunto sei mesi prima per risolvere un altro problema di layout, deforma silenziosamente ogni codice a barre della pagina. Nessun avviso. Il PDF sembra corretto. Lo scanner no.

3. La quantizzazione del generatore PDF

Quando il browser serializza in PDF, converte il risultato disegnato in operatori PDF. Alcuni generatori, in particolare Chromium, agganciano le coordinate a una griglia interna fissa. Per un codice SVG posizionato su coordinate non allineate a quella griglia, il risultato è quasi corretto ma accumula errore.

4. La codifica basata su font è ancora peggiore

Alcuni team usano un font Code 128 ({ font: "Code128" }, digitano i dati e sperano). I font sono vettoriali e teoricamente scalabili, ma l’hinting a piccole dimensioni sposta le larghezze per migliorare la resa agli occhi umani: esattamente il contrario di ciò che serve a uno scanner.

L’approccio con rendering strutturato

gPdf prende i dati, calcola il pattern barre/spazi dalla specifica GS1-128 ed emette primitive vettoriali PDF direttamente: niente HTML, nessuna traduzione SVG, nessun hinting dei font.

{
  "pages": [{
    "size": "label_100_150",
    "elements": [
      {
        "type": "barcode",
        "format": "gs1128",
        "content": "(00)123456789012345678",
        "x": 4,
        "y": 8,
        "width": 58.0,
        "height": 18.0,
        "barcode_text": { "enabled": true, "position": "bottom" }
      }
    ]
  }]
}

Per un elemento barcode, width è la lunghezza totale del simbolo (in mm), quella che misurereste con un calibro sull’etichetta stampata. È il controllo giusto da impostare, ed è ciò che width: 58.0 garantisce:

  • Il motore calcola la X-dimension dividendo la lunghezza target per il numero di barre del simbolo, completamente determinato dai dati.
  • Disegna ogni barra con esattamente la stessa X-dimension.
  • Scrive quelle larghezze nel PDF come coordinate floating-point (unità PDF = 1/72 di pollice, più fine di quanto serva alla risoluzione di scansione).
  • Niente hinting dei font, arrotondamenti dei pixel CSS o deformazioni da passaggio di layout.

Risultato: la lunghezza totale resta entro 0,1 mm dal target richiesto su ogni stampante che non applichi una propria scala (la maggior parte non lo fa per impostazione predefinita).

Che cosa stampare davvero

Tre regole evitano il 95% degli errori di lettura in produzione.

Regola 1: specificate la lunghezza totale, non la X-dimension

Il campo width è il controllo corretto perché è misurabile: potete prendere un calibro, misurare l’etichetta stampata e verificarla direttamente. Specificare invece la X-dimension significa che la lunghezza del simbolo dipende dalla quantità di dati codificata, rendendo più difficile la QA dell’etichetta (SKU diverso = larghezza diversa del codice).

Per i formati di etichetta più comuni:

  • Etichetta di spedizione 4x6 in: 100 mm di larghezza, GS1-128 intorno a 58-72 mm
  • Etichetta di conformità 4x4 in: circa 45-58 mm
  • Etichetta cartone 2x1 in (Amazon UPC): non è territorio GS1-128, usate UPC-A

Regola 2: quiet zone, sempre

Un GS1-128 richiede quiet zone >= 10X su entrambi i lati: spazio bianco vuoto che lo scanner usa per trovare i bordi del simbolo. A ingrandimento 1,0x (X = 0,495 mm), significa almeno 4,95 mm di spazio libero.

Errore classico: uno sviluppatore posiziona il codice a x: 0 per farlo stare accanto ad altri elementi dell’etichetta, e lo scanner non trova l’inizio. Il motore dovrebbe riservare automaticamente le quiet zone (gPdf lo fa); verificate il vostro.

Regola 3: provate sullo scanner target, non su quello di sviluppo

Lo scanner della fotocamera del telefono è più tollerante di uno scanner industriale Honeywell o Zebra. Il percorso QA standard:

  1. Stampate 50 etichette sulla stampante reale di produzione, alla velocità di produzione.
  2. Passatele nello stesso tipo di scanner reale, alla velocità reale del nastro.
  3. Tasso di lettura < 99% significa che qualcosa non va, di solito nella coerenza della X-dimension.

Non spedite a partner logistici sulla base di “sul mio MacBook si leggeva bene”.

Realtà multi-formato

La vostra etichetta probabilmente richiede più di GS1-128. Combinazioni comuni:

Simbolo Uso Fonte della specifica
GS1-128 Unità logistiche, GTIN + seriale + lotto GS1 General Specifications
QR with FNC1 Ecommerce scansionabile da mobile ISO/IEC 18004
Data Matrix Farmaceutico (DSCSA / EU FMD) ISO/IEC 16022
PDF417 Patenti, carte d’imbarco ISO/IEC 15438
Aztec Biglietti di trasporto ISO/IEC 24778
MaxiCode Specifico UPS ISO/IEC 16023

Un motore che gestisce solo GS1-128 finirà per spingervi verso un secondo strumento. Noi includiamo tutti e sei i formati in un unico motore perché i processi di spedizione e logistica richiedono quasi sempre almeno due formati.

Gestire i rifiuti scanner in produzione

Se siete già in produzione con un problema di rifiuti scanner, l’ordine diagnostico è questo:

  1. Campionate le etichette fallite: non affidatevi alle metriche aggregate. Recuperate l’etichetta fisica che ha fallito.
  2. Misurate con un calibro: lunghezza totale e X-dimension. Se non sono entro la tolleranza della specifica, quello è il bug.
  3. Controllate il testo leggibile sotto il simbolo: gli scanner che falliscono sulle barre spesso tentano fallback OCR. Se falliscono entrambi, il simbolo è davvero malformato.
  4. Verificate le quiet zone: misurate lo spazio bianco su entrambi i lati. Se qualcosa è stampato troppo vicino (logo, linea divisoria, altro codice a barre), il problema è quello.
  5. Provate un altro modello di scanner: alcuni scanner hanno peculiarità firmware. Se il modello A legge l’etichetta e il modello B no, è un problema di interoperabilità, non del motore.
  6. Confrontate con un’etichetta di riferimento corretta: i fornitori pubblicano immagini di riferimento con specifiche esatte. Se la vostra non corrisponde visivamente, risalite dalla differenza.

TL;DR

La precisione GS1-128 non riguarda quanto sottili possano essere le barre: riguarda la coerenza della X-dimension lungo l’intero simbolo entro una frazione di millimetro. I motori basati su HTML/CSS introducono deriva sub-pixel in più punti della pipeline; i motori strutturati che emettono direttamente primitive vettoriali PDF saltano del tutto quelle fonti di deriva.

Se vedete un tasso di rifiuto scanner dell’1-5% con il vostro stack PDF attuale, quello è l’indizio principale. Il Playground può generare un campione GS1-128 con il campo width impostato esattamente sulla specifica della vostra etichetta: misurate la stampa con un calibro e confrontate.