En strekkode på en fraktetikett eller en faktura har én jobb, og det er å bli lest av en skanner på første forsøk. Om den overlever dette forsøket, avgjøres lenge før pakken når kaia. Det avgjøres av hvordan symbolet ble plassert på siden. Den vanligste feilen i en Delphi-rapportgenerering er å rendre strekkoden som et bitmapbilde et annet sted og plassere dette bildet inn i PDF-en. Det ser fint ut på skjermen på ett zoomnivå, og forringes deretter overalt ellers.
Alternativet er å tegne symbolet som vektorinnhold, direkte på siden. PDFlibPas tilbyr en rekke tegnekall for akkurat dette, som dekker 2D-matrise-symbolene QR, PDF417 og DataMatrix, de lineære familiene Code128 og GS1-128, samt USPS Intelligent Mail for postautomatisering. Argumentet for vektor er ikke estetisk. Det handler om hvorvidt strekene havner der skanneren forventer dem.
Hvorfor vektorgrafikk er bedre enn plassert punktgrafikk
En strekkode er et mønster av streker og mellomrom, eller i to dimensjoner et rutenett av mørke og lyse moduler. Dekoderen fungerer ved å måle forholdet mellom disse breddene. Alt som forvrenger forholdene er støy som spiser av symbolets feilmargin. Et rasterisert strekkodebilde inneholder faste piksler. Når PDF-en rendres to en skriver der punktene ikke går opp i bildets rutenett, må rasteriseringen resample, og modulkanter som burde vært skarpe blir spredt over to enhetspiksler. En smal strek kan bli tykkere, et tilstøtende mellomrom tynnere, og breddeforholdet dekoderen stoler på begynner å drive.
Tegnet som vektorinnhold, er det samme symbolet et sett med fylte rektangler beskrevet i PDF-ens brukerkoordinater. Det er intet fast pikselrutenett å kjempe mot. Ved utskrift rendrer enheten hvert rektangel med den oppløsningen den faktisk har, slik at hver modulkant blir så skarp som maskinvaren tillater, uansett skala og utskriftsstørrelse. Skaler et vektorsymbol opp for en palleetikett eller krymp det for en pakke, og geometrien forblir nøyaktig. Denne presisjonen er det som holder leseraten på første forsøk høy, noe som er hele poenget med å plassere en strekkode på siden.
QR-koder og de fire feilrettingsnivåene
QR er et 2D-matrise-symbol som leses i begge akser samtidig, og det er derfor det pakker mye data inn i et lite kvadrat. Skadetoleransen kommer fra Reed-Solomon-feilretting, som tilbys på fire nivåer. Nivå L gjenoppretter omtrent 7 prosent av kodeordene, M omtrent 15 prosent, Q omtrent 25 prosent og H omtrent 30 prosent. Høyere feilretting er ikke gratis. Gjenopprettingskodeordene opptar modulkapasitet, så for en gitt mengde data vil et høyere nivå tvinge frem et tettere eller fysisk større symbol.
Kompromisset handler om miljøet symbolet skal leve i. Et rent digitalt dokument som kun skal skannes fra en skjerm, kan ligge på L og forbli kompakt. En etikett som skal trykkes, håndteres, slites og kanskje delvis dekkes av tape, krever Q eller H, fordi den ekstra redundansen er det som lar en dekoder rekonstruere innholdet fra et symbol som ikke lenger er perfekt. DrawQRCode takes position and SymbolSize that fixes the drawn width and height, plus EncodeOptions value that selects the data mode (0 for automatic, or numeric, alphanumeric, ISO-8859-1, and UTF-8 variants) and DrawOptions value for orientation.
var
Pdf: TPDFlib;
begin
Pdf := TPDFlib.Create(nil);
try
Pdf.NewDocument;
Pdf.SetPageSize('A4');
Pdf.SetMeasurementUnits(1); // 1 = millimetres
Pdf.NewPage;
// 30 mm square QR, automatic encoding, normal orientation
Pdf.DrawQRCode(20, 20, 30, 'https://www.loslab.com/', 0, 0);
Pdf.SaveToFile('Label_QR.pdf');
finally
Pdf.Free;
end;
end;
Selve feilrettingsnivået velges av koderen for å passe dataene inn i symbolet du ba om. Hvis du trenger et garantert høyt nivå for et tøft miljø, bør du dimensjonere symbolet sjenerøst, slik at koderen har nok modulbudsjett til overs for redundans i stedet for å bli tvunget ned for å passe.
PDF417 for ID-kort og fraktetiketter
PDF417 er et stablet lineært symbol. Hver rad er en kort lineær strekkode, og radene stables for å danne en blokk. Det er derfor det vises på førerkort, ombordstigningskort og fraktetiketter der en bredere stripe med data må plasseres innenfor et rektangulært avtrykk. Feilrettingen fungerer på en skala fra 0 til 8. Hvert trinn dobler omtrent antallet feilrettingskodeord, slik at nivå 5 bærer langt mer redundans enn nivå 1, på bekostning av flere kodeord på siden.
Formen på en PDF417-blokk kan justeres, og det er viktig fordi etiketten har et begrenset område å fylle. DrawPDF417SymbolEx eksponerer kontrollene det grunnleggende kallet ikke gjør. FixedColumns og FixedRows låser datakolonneantallet og radantallet, der 0 betyr at koderen bestemmer. ErrorLevel tar -1 for automatisk eller en eksplisitt 0 til 8. ModuleSize er bredden på det smaleste elementet i den gjeldende måleenheten, og HeightWidthRatio bestemmer hvor høy hver modul er i forhold til bredden sin, som er måten du gjør blokken kort og bred eller høy og smal for å passe til plassen du har.
// Fixed 10 data columns, automatic rows, error level 5,
// module 0.30 mm wide, rows three times the module width tall
Pdf.DrawPDF417SymbolEx(20, 60, 'PDF417 PAYLOAD 0123456789',
0, // Options: 0 = normal orientation
10, // FixedColumns
0, // FixedRows: 0 = automatic
5, // ErrorLevel: 0 to 8
0.30, // ModuleSize, in the current measurement unit
3.0); // HeightWidthRatio
Å låse kolonner er den vanlige metoden på en etikettmal. Et konstant kolonneantall gir blokken en forutsigbar bredde, slik at oppsettet rundt ikke forskyver seg når lengden på dataene endres fra ett dokument til det neste, mens koderen legger til rader nedover for å ta opp forskjellen.
DataMatrix for små markeringer
DataMatrix er symbolet man bør velge når markeringen må være liten. Det er et kompakt 2D-rutenett som bruker ECC 200, den moderne Reed-Solomon-metoden, og det forblir lesbart i størrelser der et QR-symbol med samme data ville vært upraktisk. Det gjør det til standardvalget for direkte delmerking, små elektroniske komponenter og tette logistikketiketter.
DrawDataMatrixSymbol tar en ModuleSize for punktavstanden, en Encoding på 1 for ASCII, og en SymbolSize som er enten 0 for automatisk eller en av de standard kvadratiske og rektangulære dimensjonene, fra 10x10 opp til 132x132. Parameteren Options kombinerer retning med bredden på den tomme sonen, der å legge til 100 til 400 setter en hvit ramme på én til fire moduler. Den tomme sonen er ikke dekorasjon. En dekoder trenger denne klare marginen for å finne symbolets mønster, og et symbol presset inntil annet blekk er et symbol som ikke kan leses.
// Auto-sized ASCII DataMatrix, 0.5 mm module, normal orientation
// with a one-module quiet zone (Options 0 + 100)
Pdf.DrawDataMatrixSymbol(20, 110, 0.5, 'DMX-SN-4408812',
1, // Encoding: 1 = ASCII
0, // SymbolSize: 0 = automatic
100); // Options: normal + one-module quiet zone
Der 1D-strekkoder fortsatt regjerer
To-dimensjonale symboler får mye oppmerksomhet, men lineære strekkoder eier fortsatt store deler av detaljhandel og logistikk, og årsaken er utbredelsen av laserskannere som leser et enkelt sveip. Code128 er arbeidshesten for alfanumeriske data, og effektiviteten kommer fra tre tegnsett. Sett A dekker kontrolltegn og store bokstaver, sett B dekker hele det utskrivbare ASCII-området, og sett C er det som betyr noe for tall. Subset C koder et par sifre i ett enkelt symboltegn, slik at en rekke med numeriske data tar halvparten så mange symboltegn som det ville gjort i sett A eller B. Dette er den mest kompakte måten å opprette en lang numerisk strekkode på, og PDFlibPas Code128-implementasjonen kombinerer B- og C-settene automatisk for å oppnå dette.
GS1-128, standarden som tidligere ble kalt EAN-128, bygger på Code128 ved å bære applikasjonsidentifikatorer, de braketterte prefiksene som forteller et mottakende system om de påfølgende sifrene er et serienummer, a batch code, or an expiry date. Strukturen er merket med FNC1, et spesielt tegn som ikke inneholder data, som markerer symbolet som GS1-kodet og skiller felt med variabel lengde. I PDFlibPas du draw a GS1-128 symbol med DrawBarcode ved å bruke Code128-typen og den bokstavelige [FNC1]-markøren plassert i datastrengen der hver applikasjonsidentifikator starter.
var
W: Double;
begin
// Code128, with FNC1 markers this becomes a GS1-128 symbol.
// AI 21 (serial) = ABC123, AI 20 (variant) = 13
Pdf.DrawBarcode(20, 150, 60, 18, '[FNC1]21ABC123[FNC1]2013',
3, // Barcode: 3 = Code128
0); // Options: 0 = default drawing
// Measure the rendered width for a 0.30 mm narrow bar before laying out
W := Pdf.GetBarcodeWidth(0.30, '[FNC1]21ABC123[FNC1]2013', 3);
end;
For post koder USPS Intelligent Mail, også kalt OneCode, ruting- og sporingsdata i en enkelt høyde-modulert strekkode for postautomatisering. DrawIntelligentMailBarcode tar eksplisitt geometri for strekbredden, den fulle strekhøyden, tracker-høyden og mellomromsbredden, der dataene leveres som en streng med bare sifre på 20, 25, 29 eller 31 siffer. De eksplisitte strek- og tracker-høydene eksisterer fordi symbolet bærer informasjon i om hver strek er en full strek, en oppstrek eller en nedstrek, og postleseren er avhengig av at disse høydene holdes etter spesifikasjonen.
Tegne på siden og måle for oppsett
Hvert kall som vises her, tegner på innholdet på den valgte siden, den samme overflaten som mottar tekst og bilder, slik at en strekkode produseres som en del av normal dokumentgenerering i stedet for å importeres som en egen ressurs. Fordi symbolene er vektorinnhold, er dataene de koder og geometrien de opptar begge kjent på tegnetidspunktet, noe som lar deg plassere dem deterministisk.
Oppsett for de lineære familiene drar nytte av å måle først. GetBarcodeWidth returnerer den totale tegnede bredden til en strekkode for en gitt smal-strek-bredde og strekkodetype, slik at du kan reservere den nøyaktige horisontale plassen før du utfører tegningen, i stedet for å gjette og oppdage en overlapp etter at siden er bygget. 2D-symbolene er enklere å plassere fordi du angir deres tegnede størrelse direkte via SymbolSize eller ModuleSize, og symbolet fyller dette avtrykket. Uansett er disiplinen den samme. Bestem den fysiske størrelsen ut fra skannemiljøet, bekreft at symbolet passer i sporet du har, og la vektorgeometrien holde alle kanter skarpe fra forhåndsvisning på skjerm til endelig utskrift.
For den bredere arbeidsflyten for sidebygging disse strekkodene faller inn under, dekker teknikkene i vår artikkel om tekst-, bilde- og fontuttrekking lesing av innhold ut av en PDF, og veiledningen for sammenslåing og splitting av store PDF-er med direkte tilgang viser hvordan man setter sammen dokumenter med store volum effektivt. Begge passer naturlig sammen med tegne-API-et beskrevet her, som leveres som en del av Delphi PDF Library for Delphi og C++Builder sammen med API-ene for tekst, grafikk, skjemaer og signaturer som er dekket andre steder på denne bloggen.