Teknisk artikel

Generering af scannbare stregkoder i PDF med HotPDF i Delphi

En stregkode er ikke et billede, man pynter et dokument med. Det er en måling, og scanneren er det instrument, der læser den. Den omformulering afgør næsten alt om, hvordan man bør tegne en ind i en PDF. Stregerne bærer ingen information ved deres sorthed; information lever i forholdet mellem stregebredder og mellemrumsbredder, og en læser genvinder den ved at time overgangene, mens en laser eller sensor fejer hen over. Klem den geometri, slør den, eller trænger ind på dens margener, og du producerer noget, der ser præcis ud som en stregkode og scanner som et plat. HotPDF giver dig to måder at sætte en på en side, og forskellen mellem dem er præcis forskellen mellem at kontrollere den geometri og opgive den

En PDF-side der viser et gitter af lineære stregkoder i forskellige symbolologier tegnet af HotPDF i Delphi
Lineære stregkode-symbolologier tegnet i en enkelt PDF med HotPDF

Hvad HotPDF kan indkode

HotPDF tegner lineære (endimensionelle) symbolologier, og sættet er bredere end de fleste projekter har brug for. THPDFBarcodeType-enumereringen dækker Code 2 of 5-familien i dens sammenflettet, industrielle og matrixformer; Code 39 og dens udvidede variant; de tre Code 128-delmængder A, B og C; Code 93 almindelig og udvidet; MSI; PostNet; Codabar; detail-UPC og EAN-gruppen, nemlig EAN-8, EAN-13, UPC-A, de komprimerede UPC-E0 og UPC-E1, og UPC-supplementet med 2- og 5-cifrede tilføjelser; og GS1-128 (EAN-128)-delmængderne. Det er nok til at dække forsyningskæde-etiketter, detailsalgssteder og de ældre industrikoder, der stadig lever i lagre

Hvad det ikke tegner, er den todimensionelle familie. Der er ingen QR, Data Matrix eller PDF417 her. Disse indkoder bytes i et gitter med deres eget fejlkorrektionsmaterialematik, og hvis et krav nævner en af dem, er dette det forkerte værktøj, og du bør vide det, inden du bygger rundt om det frem for bagefter. For endimensionelle koder er det praktiske spørgsmål snævrere: hvilken symbolologi accepterer de data, du faktisk har, fordi kodningerne ikke er udskiftelige

Databegrænsningerne er reelle, og de bider ved genereringstidspunktet. Code 2 of 5-varianterne og MSI tager kun cifre. Code 39 bærer store bogstaver, cifre og en håndfuld tegnsætningstegn; hvis du har brug for småbogstaver eller hele ASCII-området, er det Code 39 Extended eller en Code 128-delmængde. Code 128C pakker to cifre i hvert symbol for tæthed, så det vil have en ligecifret numerisk streng og intet andet. EAN-13 forventer tolv cifre og beregner den trettende som kontrol; EAN-8 forventer syv og beregner den ottende; UPC-A tager tolv. Giv en symbolologi data, den ikke kan repræsentere, og du får ikke en hjælpsom undtagelse, du får en stregkode, der indkoder affald, hvilket er værre, fordi det ser fint ud, indtil nogen scanner det ved en kasse

To tegneveje, to niveauer af kontrol

Den metode, der er bedst i produktion, er DrawBarcode, på sideobjektet. Den tager symbolologien, en position, en højde og én parameter, der betyder mere end resten: MUnit, modulbredden. Modulet er bredden af den smalleste streg, atomet, som enhver anden måling i koden er et multiplum af, og det udtrykkes her i punkter. Alt ved, om det trykte resultat scanner, spores tilbage til det ene heltal

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;

To argumenter fortjener et nærmere kig. UseCheckSum tilføjer det modulo-10-kontrolciffer, som symbolologien forventer, og for detailkoderne vil du næsten altid have det til True; slå det fra kun når dine data allerede bærer en forberegnet kontrol, ellers får du et dobbelt ciffer. Streg- og baggrundsfarverne er de to sidste parametre, og fristelsen til at være kreativ der er en fælde, der diskuteres nedenfor. Bemærk også koordinatoprindelsen: ligesom alle andre tegne­kald i HotPDF måler X og Y fra sidens nederste venstre hjørne i punkter, med Y stigende opad, den samme konvention som Hello World-eksemplet gennemgår

Den anden vej er DirectDrawBarcode, som tager data og en afgrænsningsboks, X, Y, Width, Height, og skalerer stregmønsteret til at fylde den bredde. Det er praktisk til at lægge koder ud i et gitter, fordi du navngiver fodaftrykket, og metoden tilpasser stregerne til det. Den bekvemmelighed er også dens fare. Når du giver den en bredde, indstiller du ikke længere modulstørrelsen; metoden deler den plads, du tillader, på tværs af det antal streger, dataene kræver, og den smalleste streg bliver, hvad end der falder ud af den division. Bed om en tæt Code 128-streng inde i en boks, der er for smal, og modulerne skrumper under, hvad enhver scanner kan opløse, lydløst. For alt, der skal scanne pålideligt, foretrækkes DrawBarcode, og MUnit sættes bevidst. Reservér DirectDrawBarcode til forhåndsvisninger og arrangementer, hvor du har målt, at de resulterende streger forbliver læsbare

Modulbredde er en opløsningsbeslutning

Her er det regnestykke, der afgør, om din etiket virker. En laserscanner og et kamera har begge en mindste funktion, de kan skelne, og den smalle streg skal lande komfortabelt over den efter udskrivning. Den vidt citerede gulvværdi for generelle lineære koder er en 13 mil smal streg, ca. 0,33 mm, og mange detail- og industriguider behandler det som et minimum frem for et mål. Oversæt det til PDF-enheder: ét punkt er 1/72 tomme, ca. 0,353 mm, så et enkelt punkt modulbredde sidder lige ved det gulv. Det er grunden til, at MUnit := 1 er den mindste værdi, du bør stole på for en kode, der er beregnet til en rigtig scanner, og hvorfor fordobling til 2 køber margin, der koster næsten ingenting på en etiket med plads tilovers

Nu forbind det med outputopløsning, fordi modulet også skal overleve printeren. På en 300 DPI laserprinter er én enhedsprik 1/300 tomme, så et ét-punkt-modul er ca. fire prikker bredt. Fire prikker er knap nok til at gengive en ren kant; tonerspredning og let registreringsfejl æder ind i det, og stregen, der målte ét punkt i din PDF, printer federe eller tyndere end specifikationen tillader. Bump modulet til 2 punkter, og du har otte prikker at arbejde med, hvilket absorberer den støj. Reglen, der er værd at internalisere: modulbredden, du indstiller i punkter, skal mappes til et helt, komfortabelt antal enhedsprikker ved din reelle udskrivningsopløsning, ikke den opløsning, du ønsker du havde. En kode, der scanner fejlfrit fra skærmen og fejler fra lagerprinter, mislykkedes næsten altid denne kontrol

Stillezonen er en del af symbolet

Den mest almindelige årsag til, at en korrekt indkodet stregkode ikke scanner, er stillezonen — den blanke margen på hver side af stregerne. Scannere bruger den tomhed til at finde, hvor koden begynder og slutter; uden den kan læseren ikke skelne den første streg fra det, der sidder ved siden af den på siden. Standarderne er specifikke. De fleste lineære symbolologier ønsker en stillezon på mindst ti gange modulbredden på hver side, og detail-UPC og EAN-koderne kræver ni moduler til venstre og syv til højre. Med et ét-punkt-modul er det ca. ti punkter, ca. en syvende tomme, garanteret hvidt mellemrum flankerende stregerne

HotPDF tegner stregerne og intet andet. Det reserverer ikke stillezonen for dig, hvilket betyder, at ansvaret er dit, og det er let at glemme. Fejlmoden er subtil: du placerer en stregkode tæt mod en tabelcellekant, eller du lader sidelayoutet trænge et logo op ved siden af det, og koden, der bestod enhver test på en blank side, holder op med at scanne, i det øjeblik den sendes inde i et rigtigt dokument. Budget margenen eksplicit. Inden du kalder DrawBarcode, efterlad mindst ti modulbredder fri plads på begge sider, og behandl enhver grafik, linje eller tekst, der trænger ind i det band, som en defekt, ikke et kosmetisk valg

Farve, kontrast og den menneskelæsbare linje

Streg- og baggrundsfarverne eksisterer, så du kan matche en brandpalet, og de er den hurtigste måde at ødelægge en fungerende kode. Scannere læser kontrast, klassisk med rødt lys, og de forventer mørke streger på et lyst felt. Sort på hvid er den eneste kombination, du bør bruge uden at teste. Mørkeblå eller mørkegrøn på hvid kan bestå; alt med lav luminanskontrast, og især røde streger, som en rødlyss­canner ser som baggrund, vil ikke. Hvis en designer beder om farvede stregkoder, er det ærlige svar, at stregerne forbliver sorte og farven går et andet sted hen på etiketten

DrawBarcode-vejen kan også gengive den menneskelæsbare tekst under stregerne — de cifre, en medarbejder taster ind, når en scanning mislykkes. Den tekst er en reserve, ikke dekoration, så når du placerer din egen billedtekst, hold den fri af stillezonen; en etiket med symbolologinavnet presset ind i sidemargen ødelægger det samme blanke mellemrum, som scanneren afhænger af. Felterne i eksemplet her, herunder TextOut til eventuelle omgivende etiketter, er de samme tegne­kald, der er dækket i rapport-output-guiden, som er stedet at gå, når stregkoden er ét element i en større sammensat side

En kort verifikationsvane

Vektorstreger er en fordel, der er værd at nævne. Fordi DrawBarcode skriver koden som PDF-tegneoperatorer frem for et rasterbillede, forbliver stregerne skarpe ved enhver zoom, og filen bærer ingen egen opløsning; den eneste opløsning, der betyder noget, er printerens. Det fritager dig ikke for testning, det betyder blot, at testen skal ske på papir. Generer en prøve, udskriv den på den laveste-opløsningsenhed, dine koder faktisk vil møde, og scan den med den samme klasse af læser, som dine brugere holder, ikke den high-end-imager på dit skrivebord. Kontroller stillezone med en lineal på udskriften, bekræft, at modulbredden overlevede turen fra punkter til prikker, og verificér, at den dekodede værdi matcher det, du indkodede, kontrolciffer og alt. Fem minutter med en rigtig scanner opfanger enhver fejl beskrevet ovenfor, og den opfanger dem, inden en palle forkert mærkede varer gør det

DrawBarcode- og DirectDrawBarcode-metoderne vist her er en del af HotPDF-komponenten til Delphi og C++Builder