Блог

Векторные и растровые barcode в PDF: chargeback, который не видно

Barcode, который идеально выглядит в Acrobat, может провалиться на складском сканере и стоить реальных денег в retailer chargebacks. Почему это происходит, сколько стоит и как проверить PDF за три минуты.

Barcode, который четко печатается на офисном принтере и проходит офисные тесты, может не читаться на thermal printer у 3PL за 8 000 км — и этот failure mode вы не увидите ни в одном тестовом окружении. Баг не проявляется в CI, не ломает QA в Adobe Acrobat и выглядит безупречно на 4K-мониторе. Он тихо стоит supply-chain командам 0,25 USD за unit в Amazon FBA inbound, 5–10 USD за non-compliant carton у Walmart, а иногда приводит к отказу принимать целые pallets на receiving dock. Баг в том, что barcode внутри PDF — это картинка barcode, а не настоящие инструкции рисования barcode. После resize в print pipeline ширина штрихов уже не имеет точности, которая нужна сканеру.

Эта статья для трех аудиторий. Любой читатель может прочитать первый раздел и понять, что поставлено на карту и какой вопрос задать PDF vendor. QA и operations leads захотят второй раздел о том, как рушится print-quality grade. Инженерам нужен третий раздел: что на самом деле лежит внутри PDF и как проверить любой файл за три минуты. Каждый слой заканчивается ясным выводом, так что можно остановиться там, где вы уже получили нужный ответ.

In one table

Question Если barcode — drawing instructions (vector) Если barcode — picture (raster PNG)
Size in the PDF ~1 KB ~50–300 KB
Survives resizing for any printer Да — принтер заново рисует по математике Нет — каждый resize снижает резкость
ISO 15416 print-quality grade Остается A Падает с A до C/D в production
Walmart SSCC-18 chargeback risk Низкий Высокий
Amazon FBA $0.25-per-unit relabel Редко Обычное дело на плохих templates
Effort to switch Выбрать renderer, который emits paths Engineering project

Если команда оценивает PDF generation service для любого workflow, который заканчивается сканированием, самый диагностичный вопрос — строка, на которой построена эта таблица: он создает drawing instructions или picture? Остальная часть статьи — развернутая версия этого вопроса.

For everyone: what actually happens, and what it costs

Story 1 — The Walmart pallet that nobody could read

Product manager поставщика утверждает новый shipping-label template. В Adobe Acrobat он выглядит отлично. На офисном принтере печатается нормально. Первая партия — 50 pallets, 200 cartons — уходит в Walmart distribution centre.

На receiving dock lumper team (contracted unloaders) сканирует SSCC-18 каждого pallet — 18-значный serial number, который уникально идентифицирует физический pallet. Три pallets из 50 не читаются с первого или второго прохода. Lumper team эскалирует проблему receiving lead. Lead открывает EDI 856 ASN — электронный manifest, который поставщик отправил заранее и где перечислен каждый SSCC на этой поставке. WMS видит, что три SSCC из manifest физически присутствуют, но не читаются. Это discrepancy.

Дальше все не драматично, а процедурно. EDI 824 application advice уходит поставщику с отметкой по shipment. Receiving вручную вводит нечитаемые SSCC из human-readable text под barcode. Shipment пропускает свой receiving slot. Compliance chargeback под “labelling violation” попадает в account поставщика: в 2026 году крупные retailers часто берут 5–10 USD за non-compliant carton, иногда за pallet. Для этой партии это 30–60 USD прямых расходов — почти округление.

Настоящая стоимость начинается дальше. Повторяющиеся labelling violations переводят поставщика в buyer review status, из-за чего будущие POs проходят через более жесткие compliance audits и менее выгодные routing tiers. Несколько плохих pallets за квартал этого не вызовут; системная проблема из-за неправильно настроенного PDF stack вызовет, потому что один и тот же template уходит в каждую поставку.

Post-mortem на инженерной стороне такого поставщика часто занимает недели, потому что команда не думает о “barcode в PDF” как о чем-то со значимой внутренней структурой. Для них это просто barcode. Открытие — что PDF содержал 300 dpi PNG bitmap, который thermal printer в DC должен был resample до 203 dpi, размазав ширины штрихов за пределы tolerance, — обычно приходит только после того, как первый chargeback summary заставляет копать глубже.

Story 2 — The Amazon FBA shipment with the slow-bleed chargeback

Эта история тише, крупнее и сложнее для обнаружения.

Fulfilled-by-Amazon seller отправляет 50 000 units одного SKU в FBA inbound. На каждом unit есть label с FNSKU — Amazon per-SKU identifier, напечатанный как barcode. На типичном плохом template 2–5 % units приезжают с unscannable barcodes в FBA warehouse: штрихи слишком размазаны, чтобы inbound scan прочитал их с первой попытки. Amazon не отказывается от shipment. Он отправляет affected units на manual relabelling и берет с seller fixed fee за relabel. В 2026 году эта fee составляет 0,25 USD за unit.

Для одной shipment на 50K units при 5 % failure rate это 625 USD прямых chargebacks. Для seller, который делает это каждый месяц, это 7 500 USD/year чистых потерь — и это только явная chargeback line. Более крупная скрытая цена: relabelled units дольше принимаются в FBA, значит они позже становятся доступны для buy box, промо-трафик проседает, а revenue падает как раз в неподходящий момент launch cycle.

Sellers часто обнаруживают это только когда вручную разбирают Amazon Seller Central FBA inbound defect & reimbursement report. До этого line item списывается как “Amazon weirdness”. Реальная root cause — barcode generator, который emits 300 dpi PNG вместо vector barcode, — находится на месяцы upstream и редко связывается с chargeback report кем-то, кто уже не проходил такое расследование.

Story 3 — The carrier exception line at UPS / FedEx

В третьем кейсе нет прямого chargeback — именно поэтому он самый незаметный.

Когда parcel попадает в UPS или FedEx sorting facility, conveyor scanner читает carrier tracking barcode за миллисекунды. Если read fails — bars размазаны за пределы tolerance, quiet zone обрезана, modulation grade D — parcel не отклоняют. Его снимают с main belt и направляют на exception-handling line, где человек вводит tracking number из human-readable text. Parcel возвращается в сеть с задержкой 12–24 hours.

Carriers обычно не выставляют за это прямой chargeback. Стоимость проявляется иначе:

  • Customer service tickets растут с вопросом “вы сказали, что отправили, где мой заказ?”
  • Customer NPS падает на shipments, которые действительно были вовремя, но ушли через manual flow.
  • Carrier account audits со временем отмечают поставщика как labelling concern. Будущие pickups проверяются внимательнее, contract renewals становятся жестче, rate negotiations ухудшаются.

Один плохой parcel почти ничего не стоит. 10 000 плохих parcels в месяц на протяжении года стоят отношений.

The thread that runs through all three

Во всех трех историях баг не в data, design, printer или scanner. Он в одном upstream-решении: barcode приехал на принтер как picture, а не как drawing instructions. Pictures не выдерживают resize под незнакомые принтеры. Drawing instructions выдерживают.

Why this is so common

Сложность не в том, чтобы создать vector barcode отдельно — современные barcode libraries умеют выдавать точный SVG. Сложность в том, чтобы встроить этот vector barcode в PDF как native PDF path operators, а не как embedded image. Перевод SVG paths в PDF path operators требует совместного проектирования PDF generator и barcode engine. Shortcut — вызвать barcode library, взять PNG output и встроить PNG как Image XObject — намного проще на уровне framework. Поэтому большинство PDF stacks выбирают его. С точки зрения склада именно этот архитектурный shortcut попадает на thermal printer и приносит chargeback.

Это вывод для неспециалиста. Если вы остановитесь здесь, у вас уже достаточно информации, чтобы задать любому PDF vendor правильный вопрос и попросить engineering team запустить трехминутную проверку внизу статьи.

For QA and ops leads: how the grade actually collapses

The standards your warehouse scanner already uses

Два ISO standards определяют, что значит “good barcode” на receiving dock:

  • ISO/IEC 15416 — для 1D linear codes (Code 128, GS1-128, ITF-14, EAN, UPC).
  • ISO/IEC 15415 — для 2D matrix codes (QR, DataMatrix, PDF417, Aztec).

Лабораторный verifier измеряет семь parameters по printed symbol и выдает одну overall grade от A (4.0) до F (0.0). ANSI scale — та же шкала в буквах. Manuals Walmart, Amazon, Target, Costco и крупных carriers ссылаются на эти standards и обычно требуют grade C or better. Ниже C считается out-of-spec; ниже D запускает chargeback machinery, о которой говорилось выше.

Семь parameters и то, что raster barcodes делают с каждым:

Parameter Что проверяет verifier Почему raster PNG ухудшает результат
Decodability Входят ли widths штрихов в tolerance? Resampling сдвигает widths out-of-spec — обычно первый parameter, который падает
Edge contrast Резкие ли переходы bar/space? Anti-aliasing при resize создает серые transition pixels
Modulation Равномерен ли light/dark contrast по symbol? Print-driver dithering превращает solid bars в dot patterns
Defects Есть ли spurious specks или voids? Resample artefacts становятся реальными ink dots на label
Min reflectance Достаточно ли темные bars? Resampling может оставить internal voids в узких bars
Symbol contrast Общий contrast bar-vs-background Lossy PDF compression сглаживает contrast
Quiet zone Нужное white margin вокруг symbol Auto-cropping tools могут съесть его

Vector barcode держит каждый parameter около A, потому что source pixel grid для resample не существует. Raster barcode обычно теряет около половины grade на parameter; сложите пять или шесть таких потерь, и average попадает в C или D. Data identical. Encoding identical. Barcode выглядит одинаково на экране. Отличается только printed symbol — а verifier и warehouse scanner измеряют printed symbol, не то, что QA видит в Acrobat.

Why printers compound the damage

Raster PNG внутри PDF проходит шесть resampling stages между “click Print” и “label exits the printer”. Каждый стоит примерно половину grade.

  1. Viewer rasterises for screen. Acrobat / PDF reader интерполирует source PNG на pixel grid монитора. Выглядит нормально — именно это обманывает QA.
  2. Print driver rasterises for paper. Driver выбирает bilinear или bicubic interpolation, чтобы поместить source pixels на printer grid. Edge contrast collapses.
  3. Colour conversion. Pipelines через CMYK или grayscale conversion дают еще один resample, часто вместе с halftone dithering. Modulation collapses.
  4. “Fit to printable area”. Многие drivers по умолчанию ставят 99 % page scaling, чтобы избежать edge clipping. Decodability уходит на долю grade.
  5. PDF/A flattening. Archival-PDF conversion часто повторно rasterises regions с transparency. Еще половина grade пропадает.
  6. Thermal head smear. Ribbon и direct-thermal media размазывают 2–4 mil от нагрева. Vector renderers компенсируют; raster sources не могут.

Сложите costs, и barcode, который вышел из renderer с grade A, приходит к scanner с grade C–D. Это operational arithmetic. Vector path operators пропускают stages 2–4 целиком, потому что source pixel grid для resample нет: printer rasteriser вычисляет bars на native DPI из mathematical specification.

Если вы QA lead и остановитесь здесь, action item простой: взять в аренду один ISO 15416 verifier (1–2K USD/week; vendors вроде Cognex, Keyence, REA VeriCube). Проверьте 50 production labels из самого объемного retailer flow. Если average grade ниже B, у вас raster-barcode problem.

For engineers: what’s actually inside the PDF

Two ways a barcode can sit on a page

PDF определяет ровно два типа visible object:

  • A path — список drawing operators (re rectangle, f fill, m/l move/line, S stroke) в floating-point coordinates. Printer rasteriser вычисляет их на native resolution устройства.
  • An Image XObject — embedded bitmap с width/height в pixels, закодированный как PNG / JPEG / raw stream. Renderer должен сопоставить source pixel grid с device pixel grid, что всегда требует resampling.

Vector Code 128 с 60 bars дает около 60 пар re/f в content stream — меньше 1 KB total. Float coordinates точны до 0.001 mm. Raster Code 128 дает один operator Do /Im0, указывающий на embedded PNG, обычно 270 KB при 300 dpi.

% Vector — what the renderer should produce
0 0 0.40 22 re f       % bar 1: 0.40mm wide, 22mm tall
0.99 0 0.40 22 re f    % bar 2 ...
1.97 0 0.40 22 re f    % ~60 lines like this, ~1 KB total

% Raster — what most stacks actually produce
348 0 0 84 0 0 cm      % scale a 348×84 pixel image to 92mm × 22mm
/Im0 Do                % insert the embedded PNG (~270 KB)

Vector сохраняет исходную specification до самого printer. Raster замораживает bars на source DPI и заставляет каждый downstream printer угадывать.

Verifying any PDF in 3 minutes

Три проверки без special tools, кроме poppler-utils и qpdf (бесплатны на Linux/Mac/WSL):

1. Увеличьте до 800 %. Vector barcodes остаются четкими на любом zoom. Raster сильно pixelates — можно считать source pixels. Самая быстрая informal check.

2. List embedded images:

$ pdfimages -list shipping-label.pdf
page  num  type    width  height color comp bpc enc      object  x-ppi  size
─────────────────────────────────────────────────────────────────────────────
   1    0  image     348      84  gray    1   1 ccitt     8 0     300   270K

Если видите row, которая совпадает с aspect ratio вашего barcode (например, 348 × 84 для wide 1D code или square для 2D), barcode — raster image. Vector barcodes в этом output вообще не появляются.

3. Inspect the content stream:

$ qpdf --qdf shipping-label.pdf - | grep -A2 -B2 ' re$'

Vector Code 128 с 60 bars дает dense cluster операторов re/f. Если там один operator Do /Im0 и рядом нет rectangles там, где должен быть barcode, это raster image.

Pro-grade verifier (Cognex, Keyence, REA VeriCube) стоит 5K+ USD и дает formal ISO 15416 report. Большинство команд доходят до него только после chargeback, который уже запустил investigation; три проверки выше бесплатно показывают, на какой стороне проблемы вы находитесь.

What gPdf does

Barcode rendering в gPdf работает через xBarcode, sister product той же команды. xBarcode — Rust barcode engine, полностью self-developed, не wrapper вокруг third-party library, который gPdf renderer вызывает напрямую. Для matrix и linear symbologies — Code 128, GS1-128, QR, Data Matrix, PDF417, Aztec, ITF, EAN, UPC и большинства других 30+ supported formats — xBarcode computes bar/cell pattern, а gPdf emits его в PDF content stream как re/f rectangle operators в float coordinates. No intermediate PNG, no source DPI, no raster surface.

Два следствия важно отметить:

  • Engine публично проверяем. xBarcode также работает как независимый бесплатный online tool на xbarcode.ai. Любой может вставить payload, скачать SVG / PNG / EPS и проверить path output до того, как поверит любым словам о том, что gPdf produces. Тот же path output попадает в ваши gPdf PDFs. Это credibility check, который claims “we emit vector barcodes” обычно не выдерживают.
  • Performance measurable. xBarcode генерирует стандартный 1D code за ~4 µs на single core (v1.5.4) — published benchmarks ставят его в 6× быстрее fast_qr и в 30× быстрее rxing. End-to-end через gPdf Cloudflare Workers runtime это дает около 30 ms p50 worldwide.

Помимо path output, xBarcode обрабатывает GS1 layer, который большинство third-party barcode libraries полностью пропускают: registry из 750+ Application Identifiers со strict / lenient validation modes, automatic FNC1 separator insertion и per-AI length and character-set checks. Строка (01)09504000059101(17)260315 валидируется against the spec до encoding, а не после chargeback.

PDF/A-1b through 4 совместимы by construction; flattener pass не нужен. Determinism exact: один и тот же DocumentRequest создает byte-identical content streams across isolates and releases.

When raster might still be acceptable

Два реальных случая:

  • Internal-only documents, которые не должны надежно сканироваться. Raster неважен — но он ничего и не экономит, потому что vector тоже бесплатен.
  • A photographic logo with a barcode locked into the artwork по marketing reasons. Scan reliability становится осознанным technical debt, а не oversight.

Для всего остального — shipping labels, FNSKU labels, payslips, invoice line-item barcodes, voucher PDFs, ticket QR codes, retail trade-item labels, pharmaceutical serialisation — vector единственный выбор, который не отправляет downstream print-pipeline gamble.

Bottom line

Когда вы выбираете PDF stack для любого workflow, который заканчивается сканированием, вопрос не “поддерживает ли он QR / Code 128 / GS1-128”. Вопрос:

When I ask for a barcode, is the result drawing instructions or an embedded picture?

Если ответ picture, у вашего scan-failure rate есть floor, который не снизить никакой X-dimension calibration, font-substitution care или printer maintenance. Walmart chargebacks, Amazon line items по 0,25 USD, carrier exception delays — это не vendor problems и не warehouse problems. Это свойство bytes, которые выходят из вашего renderer.

Самое дешевое действие сегодня — запустить pdfimages -list по последним 100 outbound label PDFs. Посчитайте rows, которые возвращаются как barcode-shaped image object. Считайте это размером unannounced compliance audit, который ждет своего часа.

See also