Blog

GS1-128-Barcodes mit 0,1 mm Genauigkeit aus JSON: ein Praxisleitfaden

GS1-128 wirkt einfach, bis Ihr Scanner bei 240 dpi nicht mehr liest. Ein pragmatischer Leitfaden zu Gesamtlänge, X-dimension, Quiet Zones und warum HTML/CSS diese Präzision erschwert.

Wenn Sie physische Waren versenden, müssen Sie früher oder später einen GS1-128-Barcode drucken, den ein echter Handscanner bei echtem Lagerlicht und aus echter Entfernung lesen muss. Das klingt trocken. In der PDF-Generierung ist es aber eine der lauteren Fehlerquellen.

Dieser Artikel erklärt, was “0,1 mm Genauigkeit” bei einem GS1-128-Barcode wirklich bedeutet, warum HTML/CSS-basierte Renderer damit kämpfen und welche wenigen Gestaltungsregeln dafür sorgen, dass ein Barcode beim ersten Druck über DHL-, FedEx-, USPS- und Amazon-Ingest-Scanner hinweg korrekt funktioniert.

Was “Barcode-Genauigkeit” wirklich bedeutet

GS1-128 (früher UCC/EAN-128) codiert Daten über Balkenbreiten und Lückenbreiten in sorgfältig abgestimmten Verhältnissen. Die atomare Einheit ist die X-dimension: die Breite des schmalsten Balkens beziehungsweise der schmalsten Lücke. Alles andere ist ein Vielfaches von X (1X, 2X, 3X, 4X für interne Code-128-Muster).

Scanner decodieren, indem sie relative Breiten messen. Wenn die gedruckten Breiten driften, schlägt die Decodierung fehl.

Die zwei häufigsten Produktionsfehler:

  1. Uneinheitliche X-dimension im Symbol: Der Renderer rundet benachbarte Balken auf Subpixel-Ebene unterschiedlich. Die ersten drei Balken sind 8 px breit, dann erscheint mitten im Symbol ein 7-px-Balken. Der Scanner sieht ein inkonsistentes Muster.
  2. Falsche Gesamtlänge oder Skalierung: Der Renderer skaliert das Symbol nach dem Rendern und drückt die X-dimension unter das GS1-Minimum, typischerweise 0,495 mm bei 1,0x Vergrößerungsfaktor.

Beides zeigt sich gleich: Ein einzelnes Muster scannt mit einem Piepton, aber ein Produktionslauf hat eine Ablehnungsrate von 1 aus 30. In QA sehen Sie das nicht, weil Ihr Entwicklungs-Scanner meist toleranter ist als der Scanner im Lager.

Die 0,1-mm-Regel

Die relevante Präzision ist die Gesamtlänge des Barcodes mit höchstens 0,1 mm Toleranz gegenüber dem Zielwert der Spezifikation. Nicht: “jeder Balken ist 0,1 mm breit”. Balken sind typischerweise 0,495 mm oder breiter. Die 0,1-mm-Grenze bezieht sich auf die kumulative Maßhaltigkeit des gesamten Symbols.

Für einen typischen GS1-128 mit 18 numerischen Zeichen:

  • Das Symbol enthält rund 120 Balken und Lücken
  • Gesamtlänge bei 1,0x Vergrößerung: etwa 58 mm
  • 0,1 mm Gesamttoleranz entspricht etwa 0,17 % Genauigkeit über die gesamte Länge
  • Daraus ergibt sich ungefähr 0,001 mm Konsistenzbudget pro Balken, also weit weniger als die Breite eines einzelnen Balkens

Deshalb ist es fatal, wenn ein Renderer einen 7-px-Balken setzt, obwohl es 7,4 px sein müssten. Subpixel-Rundung addiert sich über 120 Balken, und irgendwo zwischen Balken 50 und Balken 80 reißen Sie die 0,1-mm-Toleranz.

Warum HTML/CSS hier kämpft

Der Weg, auf dem viele Teams landen: GS1-128-Daten in eine Zeichenfolge codieren, ein SVG erzeugen (oder schlimmer: einzelne <div>-Balken), in HTML einbetten und per Puppeteer oder Prince als PDF rendern.

Jedes Glied dieser Kette kann Drift einführen:

1. Browser-Rasterisierung rundet

Selbst SVG in HTML wird vom Browser-Painter auf Subpixel gerundet, sofern nicht shape-rendering="crispEdges" gesetzt ist, der umgebende Container auf einer ganzzahligen Pixelgrenze liegt und die PDF-DPI sauber in die Balkenbreiten passt. Drei Bedingungen, die alle leicht versehentlich verletzt werden.

2. CSS-Layout verschiebt Maße

Ein transform: scale(0.95) irgendwo in Ihrem Stylesheet, vielleicht vor sechs Monaten zur Lösung eines ganz anderen Layoutproblems eingeführt, verzerrt still jeden Barcode auf der Seite. Es gibt keine Warnung. Das PDF sieht gut aus. Der Scanner nicht.

3. Der PDF-Emitter quantisiert selbst

Wenn der Browser nach PDF serialisiert, konvertiert er das gemalte Ergebnis in PDF-Zeichenoperatoren. Manche Emitter, insbesondere der von Chromium, rasten auf ein festes PDF-internes Gitter ein. Bei einem SVG-Barcode auf Koordinaten, die nicht sauber zu diesem Gitter passen, entsteht eine Ausgabe, die fast korrekt ist, aber Fehler aufsummiert.

4. Font-basierte Codierung ist noch schlechter

Manche Teams verwenden einen Code-128-Font ({ font: "Code128" }, Daten eintippen, hoffen). Fonts sind vektoriell und theoretisch skalierbar, aber Font Hinting bei kleinen Größen verschiebt Breiten absichtlich so, dass sie für Menschen besser aussehen. Für Scanner ist genau das falsch.

Der strukturierte Rendering-Ansatz

gPdf nimmt die Daten, berechnet das Balken-/Lückenmuster aus der GS1-128-Spezifikation und schreibt PDF-Vektorprimitive direkt: kein HTML, keine SVG-Übersetzung, kein Font Hinting.

{
  "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" }
      }
    ]
  }]
}

Bei einem barcode-Element ist width die Gesamtlänge des Symbols in Millimetern, also das, was Sie auf dem gedruckten Label mit dem Messschieber prüfen würden. Genau das ist der richtige Regler. width: 58.0 garantiert:

  • Der Renderer berechnet die X-dimension, indem er die Zielbreite durch die vollständig aus den Daten bestimmte Balkenanzahl teilt.
  • Er zeichnet jeden Balken mit exakt derselben X-dimension.
  • Er schreibt diese Breiten als Floating-Point-Koordinaten in das PDF (PDF-Einheit = 1/72 inch, feiner als für Scannerauflösung nötig).
  • Kein Font Hinting, kein CSS-Pixelrunden, keine Verzerrung durch einen Layout-Pass.

Das Ergebnis: Die Gesamtlänge bleibt innerhalb von 0,1 mm des angeforderten Zielwerts, solange der Drucker nicht selbst zusätzliche Skalierung anwendet. Die meisten tun das standardmäßig nicht.

Was Sie tatsächlich drucken sollten

Drei Regeln verhindern etwa 95 % der Scannerfehler in Produktion.

Regel 1: Gesamtlänge angeben, nicht X-dimension

Das Feld width ist der richtige Regler, weil es messbar ist: Sie können ein gedrucktes Label mit dem Messschieber prüfen. Wenn Sie stattdessen die X-dimension angeben, hängt die Symbolbreite von der Länge der codierten Daten ab. Das erschwert Label-QA, weil eine andere SKU eine andere Barcodebreite erzeugt.

Für typische Labelgrößen:

  • 4 x 6 Zoll Versandlabel: 100 mm breit, GS1-128 sollte etwa 58 bis 72 mm lang sein
  • 4 x 4 Zoll Compliance-Label: etwa 45 bis 58 mm
  • 2 x 1 Zoll Kartonlabel (Amazon UPC): nicht GS1-128, hier UPC-A verwenden

Regel 2: Quiet Zones, immer

GS1-128 braucht auf beiden Seiten Quiet Zones von mindestens 10X, also leeren Weißraum, den der Scanner nutzt, um die Kanten des Symbols zu finden. Bei 1,0x Vergrößerung (X = 0,495 mm) sind das mindestens 4,95 mm freier Raum.

Der klassische Fehler: Ein Entwickler setzt den Barcode auf x: 0, damit er neben andere Label-Elemente passt. Der Scanner findet den Start nicht. Ein Renderer sollte Quiet Zones automatisch reservieren; gPdf tut das. Prüfen Sie Ihren trotzdem.

Regel 3: Auf dem echten Zielscanner testen, nicht auf Ihrem Entwicklungsgerät

Die Kamera Ihres Smartphones ist toleranter als ein industrieller Honeywell- oder Zebra-Scanner. Der Standard-QA-Pfad:

  1. 50 Labels auf dem echten Produktionsdrucker und mit Produktionsgeschwindigkeit drucken.
  2. Diese Labels mit dem echten Scannertyp und der echten Fördergeschwindigkeit testen.
  3. Leserate unter 99 % bedeutet: Etwas stimmt nicht, meistens die Konsistenz der X-dimension.

Versenden Sie nicht an Logistikpartner auf Basis von “scannt auf meiner MacBook-Kamera”.

Multi-Format-Realität

Ihr Label braucht wahrscheinlich mehr als GS1-128. Häufige Kombinationen:

Symbol Einsatz Spezifikationsquelle
GS1-128 Logistikeinheiten, GTIN + serial + lot GS1 General Specifications
QR with FNC1 Mobil scannbarer E-Commerce ISO/IEC 18004
Data Matrix Pharma (DSCSA / EU FMD) ISO/IEC 16022
PDF417 Führerscheine, Bordkarten ISO/IEC 15438
Aztec Verkehrstickets ISO/IEC 24778
MaxiCode Speziell UPS ISO/IEC 16023

Ein Renderer, der nur GS1-128 beherrscht, zwingt Sie irgendwann zu einem zweiten Tool. Wir bündeln alle sechs Formate in einem Renderer, weil Versand- und Logistik-Workflows fast immer mindestens zwei benötigen.

Scanner-Ablehnungen in Produktion behandeln

Wenn Sie bereits in Produktion Scanner-Ablehnungen sehen, gehen Sie diagnostisch in dieser Reihenfolge vor:

  1. Fehlgeschlagene Labels sammeln: Verlassen Sie sich nicht auf aggregierte Metriken. Beschaffen Sie das tatsächliche physische Label, das gescheitert ist.
  2. Mit Messschieber messen: Gesamtlänge und X-dimension. Wenn sie nicht innerhalb der Spezifikationstoleranz liegen, ist das Ihr Bug.
  3. Menschenlesbaren Text darunter prüfen: Scanner, die an den Balken scheitern, versuchen häufig OCR-Fallback. Wenn beides fehlschlägt, ist das Symbol wirklich fehlerhaft.
  4. Quiet Zones verifizieren: Weißraum auf beiden Seiten messen. Wenn etwas zu nah gedruckt wurde, etwa ein Logo, eine Trennlinie oder ein anderer Barcode, ist das das Problem.
  5. Ein anderes Scanner-Modell testen: Manche Scanner haben Firmware-Eigenheiten. Wenn Modell A das Label liest und Modell B nicht, ist Interoperabilität das Thema, nicht nur Ihr Renderer.
  6. Mit einem bekannten guten Referenzlabel vergleichen: Anbieter veröffentlichen Referenzbilder mit exakten Spezifikationen. Wenn Ihres visuell abweicht, arbeiten Sie von diesem Unterschied zurück.

TL;DR

GS1-128-Präzision bedeutet nicht, wie dünn Sie Balken drucken können. Entscheidend ist, ob die X-dimension über das gesamte Symbol innerhalb eines Bruchteils eines Millimeters konsistent bleibt. HTML/CSS-basierte Renderer führen an mehreren Stellen der Pipeline Subpixel-Drift ein; strukturierte Renderer, die PDF-Vektorprimitive direkt ausgeben, umgehen diese Driftquellen vollständig.

Wenn Sie mit Ihrem aktuellen PDF-Stack eine Scanner-Ablehnungsrate von 1 bis 5 % sehen, ist das der Smoking Gun. Der Playground kann ein GS1-128-Beispiel rendern, bei dem das Feld width exakt auf Ihre Labelspezifikation gesetzt ist. Drucken Sie das Ergebnis, messen Sie es mit dem Messschieber und vergleichen Sie.