Technical Article

Generiranje berljivih črtnih kod v PDF s HotPDF v Delphi

Črtna koda ni le slika za okrasitev dokumenta. Gre za meritev, čitalnik pa je instrument, ki jo bere. Ta pogled določa skoraj vse o tem, kako jo morate izrisati v PDF. Črne črte same po sebi ne prenašajo informacij; informacije živijo v razmerju med širinami črt in širinami presledkov, čitalnik pa jih razbere z merjenjem časovnih prehodov, ko laser ali senzor potuje čezenj. Če to geometrijo stisnete, zabrišete ali natrpate njene robove, boste dobili nekaj, kar je videti natanko kot črtna koda, vendar se bere kot navaden madež. HotPDF ponuja dva načina za postavitev črtne kode na stran, razlika med njima pa je ravno v tem, ali to geometrijo nadzorujete ali pa jo prepustite naključju.

Simbologije linearnih črtnih kod, izrisane v en sam PDF s HotPDF
Linearne simbologije črtnih kod, izrisane v en sam PDF s HotPDF

Kaj lahko HotPDF kodira

HotPDF riše linearne (enodimenzionalne) simbologije in njihov nabor je širši, kot potrebuje večina projektov. Enumeracija THPDFBarcodeType pokriva družino Code 2 of 5 v njenih prepletenih (interleaved), industrijskih in matričnih oblikah; Code 39 in njegovo razširjeno verigo; tri podnabori Code 128 A, B in C; Code 93 (navaden in razširjen); MSI; PostNet; Codabar; skupino EAN/UPC za maloprodajo (EAN-8, EAN-13, UPC-A, stisnjeni različici UPC-E0 in UPC-E1 ter dodatka UPC z 2 in 5 številkami) ter podnaborje GS1-128 (EAN-128). To zadošča za pokrivanje etiket v oskrbovalni verigi, maloprodajnih mest in starejših industrijskih kod, ki so še vedno v uporabi v skladiščih.

Česar pa ne podpira, je dvodimenzionalna družina kod. Tukaj ne boste našli kod QR, Data Matrix ali PDF417. Te kodirajo bajte v mreži z lastno matematiko za odpravljanje napak, in če vaša zahteva vključuje eno izmed njih, to ni pravo orodje – kar je dobro vedeti pred načrtovanjem in ne šele po njem. Pri enodimenzionalnih kodah je praktično vprašanje ožje: katera simbologija sprejema podatke, ki jih dejansko imate, saj kodiranja niso medsebojno zamenljiva.

Omejitve podatkov so resnične in vplivajo na proces generiranja. Različice Code 2 of 5 in MSI sprejemajo samo številke. Code 39 podpira velike črke, številke in nekaj ločil; če potrebujete male črke ali celoten nabor ASCII, morate uporabiti Code 39 Extended ali podnabor Code 128. Code 128C zaradi gostote pakira po dve števki v vsak simbol, zato zahteva številski niz s sodim številom znakov in nič drugega. EAN-13 pričakuje dvanajst števk in izračuna trinajsto kot kontrolno; EAN-8 pričakuje sedem števk in izračuna osmo; UPC-A sprejme dvanajst. Če simbologiji posredujete podatke, ki jih ne more predstaviti, ne boste prejeli izjeme, temveč črtno kodo, ki kodira nesmiselne podatke – kar je še slabše, saj je videti povsem v redu, dokler je nekdo ne poskuša prebrati na blagajni.

Dve poti izrisa, dve ravni nadzora

Metoda, po kateri boste posegli v produkciji, je DrawBarcode na objektu strani. Sprejme simbologijo, položaj, višino in en parameter, ki je pomembnejši od vseh ostalih: MUnit – širino modula. Modul predstavlja širino najtanjše črte, osnovni gradnik, od katerega so odvisne vse ostale širine v kodi, in je tukaj izražen v točkah. Vprašanje, ali bo natisnjen rezultat berljiv, je v celoti odvisno od tega celega števila.

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'label.pdf';
    Pdf.BeginDoc;

    // BCType, X, Y, Height, MUnit (module width in points), angle,
    // data, UseCheckSum, bar color, background color.
    Pdf.CurrentPage.DrawBarcode(
      bcCodeEAN13,           // symbology
      72, 680,               // X, Y in points from the bottom-left
      60,                    // bar height
      1,                     // MUnit: 1pt narrowest bar
      0,                     // no rotation
      '123456789012',        // 12 digits; the 13th is the check
      True,                  // append the modulo-10 check digit
      clBlack, clWhite);     // bars black, background white

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Dva argumenta si zaslužita podrobnejši pregled. Zastavica UseCheckSum doda kontrolno številko po modulu 10, ki jo simbologija pričakuje, in za maloprodajne kode boste skoraj vedno želeli, da je True. Izklopite jo le, če vaši podatki že vsebujejo vnaprej izračunano kontrolno številko, sicer boste dobili podvojeno številko. Barva črt in barva ozadja sta zadnja dva parametra, skušnjava po ustvarjalnosti pri njuni izbiri pa je past, ki jo obravnavamo v nadaljevanju. Bodite pozorni tudi na koordinatno izhodišče: kot pri vseh drugih klicih za risanje v HotPDF se X in Y merita v točkah od spodnjega levega kota strani navzgor, kar je enaka konvencija, kot jo opisuje primer Hello World.

Druga pot je DirectDrawBarcode, ki sprejme podatke in omejevalni okvir X, Y, Width, Height ter prilagodi vzorec črt, da zapolni to širino. To je priročno za razporejanje kod na mreži, saj določete velikost, metoda pa črte prilagodi temu prostoru. Ta priročnost pa skriva tudi nevarnost. Ko določite širino, ne nastavljate več širine modula; metoda razdeli razpoložljivi prostor med toliko črt, kolikor jih podatki zahtevajo, najtanjša črta pa postane tisto, kar izide iz te delitve. Če zahtevate gost niz Code 128 znotraj preozkega okvirja, se bodo moduli tiho zmanjšali pod mejo, ki jo čitalnik še lahko razloči. Za vse kode, ki jih je treba zanesljivo brati, uporabljajte DrawBarcode in premišljeno nastavite MUnit. Uporabo DirectDrawBarcode pa prihranite za predoglede in postavitve, kjer ste izmerili, da izrisane črte ostajajo dovolj široke.

Širina modula je odločitev o ločljivosti

Tukaj je izračun, ki določa, ali bo vaša etiketa delovala. Laserski čitalnik in kamera imata določeno najmanjšo velikost elementa, ki jo še lahko razločita, najtanjša črta pa mora po tiskanju pristati nad to mejo. Splošno sprejeta najnižja meja za linearne kode splošne rabe je 13 milov (približno 0,33 mm) za najtanjšo črto, številni maloprodajni in industrijski priročniki pa to obravnavajo kot minimum in ne kot cilj. Prevedeno v enote PDF: ena točka je 1/72 palca oziroma približno 0,353 mm, zato se širina modula ene točke nahaja tik ob tej spodnji meji. Zato je MUnit := 1 najmanjša vrednost, ki ji lahko zaupate za kodo, namenjeno branju s pravim čitalnikom, njeno podvojitev na 2 pa prinaša varnostno rezervo, ki na etiketi z dovolj prostora ne stane skoraj nič.

Sedaj to povežite z ločljivostjo izhoda, saj mora modul preživeti tudi tiskanje. Na tiskalniku z ločljivostjo 300 DPI je ena pika naprave enaka 1/300 palca, zato je enotočkovni modul širok približno štiri pike. Štiri pike komaj zadoščajo za izris čistega roba; razlivanje tonerja in majhne napake pri poravnavi lahko zmanjšajo to širino, zato se lahko črta, ki je v PDF-ju merila eno točko, natisne širša ali ožja, kot dovoljuje specifikacija. Povečajte modul na 2 točki in imeli boste osem pik prostora, kar absorbira ta šum. Pravilo, ki si ga velja zapomniti: širina modula v točkah se mora preslikati v celo, varno število pik naprave pri vaši dejanski ločljivosti tiskanja in ne pri ločljivosti, ki bi jo želeli imeti. Koda, ki se brez težav bere z zaslona in odpove na skladiščnem tiskalniku, skoraj vedno ni prestala tega preizkusa.

Tiho območje je del simbola

Tiho območje (quiet zone) – prazen prostor na vsaki strani črt – je najpogostejši razlog, zakaj se črtna koda ne prebere. Čitalniki uporabljajo ta prazen prostor, da ugotovijo, kje se koda začne in konča; brez njega bralnik ne more ločiti prve črte od ostale vsebine na strani. Standardi so natančni. Večina linearnih simbologij zahteva tiho območje v širini vsaj desetkratnika širine modula na vsaki strani, maloprodajne kode UPC in EAN pa zahtevajo devet modulov na levi in sedem na desni. Pri enotočkovnem modulu to pomeni približno 10 točk (okoli sedmina palca) zagotovljenega praznega prostora na obeh straneh črt.

HotPDF izriše črte in nič druga. Tihega območja ne rezervira namesto vas, kar pomeni, da je ta naloga vaša in jo je enostavno pozabiti. Napaka se pokaže na precej neopazen način: črtno kodo postavite tik ob rob celice v tabeli ali pa obnjo natrpate logotip podjetja. Koda, ki je uspešno prestala vse preizkuse na prazni strani, se nenadoma ne bere več, ko jo postavite v pravi dokument. Ta rob načrtujte izrecno. Pred klicem DrawBarcode pustite vsaj deset širin modula praznega prostora na obeh straneh, vsako grafiko, črto ali besedilo, ki posega v ta pas, pa obravnavajte kot napako in ne kot estetsko izbiro.

Barva, kontrast in vrstica, berljiva za ljudi

Barve črt in ozadja so na voljo zato, da jih lahko uskladite s celostno grafično podobo blagovne znamke, vendar so hkrati najhitrejša pot, da pokvarite delujočo kodo. Čitalniki zaznavajo kontrast (običajno z rdečo svetlobo) in pričakujejo temne črte na svetlem ozadju. Črna na beli je edina kombinacija, ki jo lahko uporabite brez predhodnega testiranja. Temno modra ali temno zelena na beli lahko delujeta; karkoli z nizkim svetlobnim kontrastom, predvsem pa rdeče črte (ki jih rdeči laser vidi kot ozadje), pa ne bo delovalo. Če oblikovalec zahteva barvne črtne kode, je edini iskren odgovor ta, da črte ostanejo črne, barvni elementi pa se postavijo drugam na etiketo.

Pot DrawBarcode lahko izriše tudi človeku berljivo besedilo pod črtami – številke, ki jih operater vnese ročno, ko branje ne uspe. To besedilo je zgolj varnostna rezerva in ne okras, zato pri postavitvi lastnih napisov poskrbite, da ne bodo posegali v tiho območje. Napis z oznako simbologije, natrpan ob stranskem robu, izniči prazen prostor, od katerega je čitalnik odvisen. Elementi v tem primeru, vključno s TextOut za okoliške napise, so enaki klici za risanje, kot jih obravnava vodnik po izpisu poročil, kamor se lahko obrnete, ko je črtna koda le eden izmed elementov na večji sestavljeni strani.

Kratka navada preverjanja

Vektorske črte so prednost, ki jo je vredno omeniti. Ker DrawBarcode zapisuje kodo kot ukazne operacije za risanje PDF in ne kot rasterizirano sliko, črte ostanejo ostre pri vsaki povečavi, datoteka pa nima lastne ločljivosti. Edina ločljivost, ki je pomembna, je ločljivost tiskalnika. To pa vas ne odvezuje testiranja – test se mora izvesti na papirju. Ustvarite vzorec, ga natisnite na tiskalniku z najnižjo ločljivostjo, ki jo bodo vaše kode dejansko srečale, in ga preberite z enako vrsto čitalnika, kot jo bodo uporabljale vaše stranke, in ne z vrhunsko napravo na vaši mizi. Preverite tiha območja z ravnilom na izpisu, potrdite, da je širina modula preživela pretvorbo iz točk v pike, in preverite, ali se dešifrirana vrednost ujema s tisto, ki ste jo kodirali (vključno s kontrolno številko). Pet minut s pravim čitalnikom odkrije vsako zgoraj opisano napako, in to še preden skladišče zapusti paleta napačno označenega blaga.

Metodi DrawBarcode in DirectDrawBarcode, prikazani tukaj, sta del komponente HotPDF Component za Delphi in C++Builder.