Brūkšninis kodas siuntimo etiketėje arba sąskaitoje faktūroje turi vienintelį darbą – būti nuskaitytas skeneriu iš pirmo karto. Ar jis sėkmingai praeis šį nuskaitymą, nusprendžiama gerokai prieš siuntai pasiekiant krovos aikštelę. Tai priklauso nuo to, kaip simbolis buvo patalpintas puslapyje. Dažniausia klaida Delphi ataskaitų kūrimo procese yra brūkšninio kodo vaizdavimas kaip rastrinio paveikslėlio (bitmap) kitur ir jo įkėlimas į PDF. Jis atrodo gerai ekrane esant vienam masteliui, bet praranda kokybę visur kitur.
Alternatyva yra piešti simbolį kaip vektorinį turinį tiesiai puslapyje. PDFlibPas siūlo piešimo iškvietimų šeimą būtent tam – ji apima 2D matricos simbolius QR, PDF417 ir DataMatrix, linijines šeimas Code128 ir GS1-128 bei USPS Intelligent Mail pašto automatizavimui. Argumentas už vektorinę grafiką nėra estetinis. Svarbiausia – ar brūkšneliai atsiduria ten, kur tikisi skeneris.
Kodėl vektorinė grafika pranašesnė už rastrinį paveikslėlį
Brūkšninis kodas yra brūkšnelių ir tarpų derinys, o dviejų dimensijų atveju – tamsių ir šviesių modulių tinklas. Dekoderis veikia matuodamas šių pločių santykį. Bet kas, kas iškraipo santykius, yra triukšmas, kuris eikvoja simbolio klaidų taisymo išteklius. Rastruotas brūkšninio kodo paveikslėlis turi fiksuotus pikselius. Kai PDF siunčiamas spausdintuvui, kurio taškai nesidalija tolygiai su vaizdo tinkleliu, rastruotuvas turi atlikti interpoliaciją (resample), o modulių kraštai, kurie turėtų būti aštrūs, pasiskirsto per du įrenginio pikselius. Siauras brūkšnelis gali pastorėti, gretimas tarpas sumažėti, o pločių santykis, kuriuo remiasi dekoderis, pakinta.
Nupieštas kaip vektorinis turinis, tas pats simbolis yra užpildytų stačiakampių rinkinys, aprašytas PDF naudotojo erdvės koordinatėmis. Nėra jokio fiksuoto pikselių tinklelio, su kuriuo reikėtų kovoti. Spausdinimo metu įrenginys atvaizduoja kiekvieną stačiakampį ta raiška, kurią jis iš tikrųjų turi, todėl kiekvienas modulio kraštas yra toks aštrus, kiek leidžia įranga, esant bet kokiam masteliui ir spaudinio dydžiui. Padidinkite vektorinį simbolį paletės etiketėms arba sumažinkite siuntai, ir geometrija liks tiksli. Šis tikslumas užtikrina aukštą nuskaitymo sėkmę iš pirmo karto, o tai ir yra pagrindinis tikslas dedant brūkšninį kodą į puslapį.
QR kodai ir keturi taisymo lygiai
QR yra 2D matricos simbolis, nuskaitomas abiem ašimis iškart, todėl jis talpina daug duomenų mažame kvadrate. Jo atsparumas pažeidimams atsiranda dėl Reed-Solomon klaidų taisymo metodo, siūlomo keturiais lygiais. L lygis atkuria maždaug 7 procentus kodų, M – apie 15 procentų, Q – apie 25 procentus, o H – apie 30 procentų. Didesnis klaidų taisymas kainuoja: atkūrimo kodai užima modulio talpą, todėl tam pačiam duomenų kiekiui didesnis taisymo lygis reikalauja tankesnio arba fiziškai didesnio simbolio.
Pasirinkimas priklauso nuo aplinkos, kurioje bus naudojamas simbolis. Švarus skaitmeninis dokumentas, kuris bus nuskaitomas tik iš ekrano, gali naudoti L lygį ir likti kompaktiškas. Etiketė, kuri bus spausdinama, naudojama, braižoma ar net iš dalies užklijuota juosta, reikalauja Q arba H lygio, nes papildomas pertekliškumas leidžia dekoderiui atkurti duomenis iš simbolio, kuris nebėra idealios būsenos. DrawQRCode priima poziciją ir SymbolSize, kuris nustato nupieštą plotį bei aukštį, taip pat EncodeOptions reikšmę, pasirenkančią duomenų režimą (0 – automatinis, arba skaitinis, raidinis-skaitinis, ISO-8859-1 ir UTF-8 variantai) bei DrawOptions reikšmę orientacijai.
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;
Patį klaidų taisymo lygį pasirenka kodavimo įrenginys, kad tilptų duomenys į jūsų pageidaujamą simbolį. Jei jums reikalingas garantuotas aukštas taisymo lygis atšiaurioje aplinkoje, parinkite didesnį simbolio dydį, kad kodavimo įrenginys turėtų modulių biudžetą pertekliškumui, užuot buvęs priverstas jį sumažinti.
PDF417 identifikavimo kortelėms ir siuntimo etiketėms
PDF417 yra sudėtinis linijinis simbolis. Kiekviena eilutė yra trumpas linijinis brūkšninis kodas, o eilutės sudaromos į bloką, todėl jis naudojamas vairuotojo pažymėjimuose, įlaipinimo kortelėse ir siuntimo etiketėse, kur didesnis duomenų kiekis turi tilpti stačiakampiame plote. Jo klaidų taisymas veikia skalėje nuo 0 iki 8. Kiekvienas žingsnis apytikriai padvigubina taisymo kodų skaičių, todėl 5 lygis turi žymiai daugiau pertekliškumo nei 1 lygis, nors tam reikia daugiau kodų vietos lape.
PDF417 bloko forma yra reguliuojama, ir tai svarbu, nes etiketė turi ribotą plotą. DrawPDF417SymbolEx suteikia kontrolę, kurios neturi pagrindinis iškvietimas. FixedColumns ir FixedRows nustato duomenų stulpelių bei eilučių skaičių (0 reiškia leisti nuspręsti pačiam kodavimo įrenginiui). ErrorLevel priima -1 automatiniam taisymui arba konkrečią reikšmę nuo 0 iki 8. ModuleSize yra siauriausio elemento plotis esamu matavimo vienetu, o HeightWidthRatio nustato, kiek kiekvienas modulis yra aukštas santykyje su savo pločiu – taip galite padaryti bloką trumpą ir platų arba aukštą ir siaurą, kad atitiktų turimą vietą.
// 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
Stulpelių skaičiaus fiksavimas yra įprastas būdas valdyti etiketės šabloną. Pastovus stulpelių skaičius suteikia blokui numatomą plotį, todėl aplinkinis išdėstymas nesikeičia keičiantis koduojamų duomenų ilgiui skirtinguose dokumentuose, o kodavimo įrenginys tiesiog prideda eilutes žemyn, kad sugertų skirtumą.
DataMatrix mažiems ženklinimams
DataMatrix yra simbolis, kurį verta rinktis, kai ženklinimas turi būti mažas. Tai yra kompaktiškas 2D tinklas, naudojantis šiuolaikinį Reed-Solomon ECC 200 metodą, ir jis išlieka nuskaitomas tokiais dydžiais, kur to paties duomenų kiekio QR kodas būtų nepatogus. Todėl jis yra standartinis pasirinkimas tiesioginiam dalių ženklinimui, smulkiems elektronikos komponentams ir tankioms logistikos etiketėms.
DrawDataMatrixSymbol priima ModuleSize taškų žingsniui, Encoding reikšmę 1 ASCII kodavimui ir SymbolSize, kuris yra 0 automatiniam parinkimui arba vienas iš standartinių kvadratinių ar stačiakampių matmenų nuo 10x10 iki 132x132. Parametras Options sujungia orientaciją su ramybės zonos (quiet zone) pločiu, kur reikšmės nuo 100 iki 400 nustato nuo vieno iki keturių modulių baltą rėmelį. Ramybės zona nėra dekoracija. Dekoderiui reikia šios tuščios vietos, kad surastų simbolio šabloną, o simbolis, prispaustas prie kito rašalo, bus sunkiai nuskaitomas.
// 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
Kur vis dar dominuoja 1D brūkšniniai kodai
Dviejų dimensijų simboliai sulaukia daug dėmesio, tačiau linijiniai brūkšniniai kodai vis dar užima didelę dalį mažmeninės prekybos ir logistikos rinkos, o priežastis – platus lazerinių skenerių, nuskaitančių vieną liniją, paplitimas. Code128 yra darbinis arkliukas raidiniams-skaitiniams duomenims, o jo efektyvumas atsiranda iš trijų simbolių rinkinių. A rinkinys apima valdymo simbolius ir didžiąsias raides, B rinkinys – visą spausdinamą ASCII diapazoną, o C rinkinys skirtas skaičiams. Poaibis C koduoja skaičių porą viename simbolyje, todėl skaitiniai duomenys užima perpus mažiau vietos nei A arba B rinkiniuose. Tai yra kompaktiškiausias būdas pateikti ilgą skaitinį brūkšninį kodą, o PDFlibPas Code128 realizacija automatiškai sujungia B ir C rinkinius tam pasiekti.
GS1-128, standartas, anksčiau vadintas EAN-128, remiasi Code128 ir naudoja taikomųjų programų identifikatorius (Application Identifiers) – skliausteliuose pateikiamus prefiksus, kurie nurodo sistemai, ar sekantys skaitmenys yra serijinis numeris, partijos kodas, ar galiojimo data. Struktūra žymima FNC1, specialiu netikru simboliu, kuris nurodo, kad simbolis užkoduotas pagal GS1 standartą, ir skiria kintamo ilgio laukus. PDFlibPas aplinkoje GS1-128 simbolį piešiate naudodami DrawBarcode su Code128 tipu ir pažymėdami [FNC1] žymę duomenų eilutėje ten, kur prasideda kiekvienas taikomosios programos identifikatorius.
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;
Paštui USPS Intelligent Mail, dar vadinamas OneCode, koduoja maršrutizavimo ir sekimo duomenis viename kintamo aukščio brūkšniniame kode, skirtame pašto automatizavimui. DrawIntelligentMailBarcode priima aiškią geometriją brūkšnelio pločiui, pilnam brūkšnelio aukščiui, sekimo (tracker) aukščiui ir tarpų pločiui, o duomenys pateikiami kaip 20, 25, 29 arba 31 skaitmens eilutė. Aiškus brūkšnelių ir sekimo elementų aukštis yra reikalingas todėl, kad simbolis perduoda informaciją priklausomai nuo to, ar brūkšnelis yra pilnas, viršutinis (ascender), ar apatinis (descender), o pašto skaitytuvas priklauso nuo to, ar šie aukščiai atitinka specifikaciją.
Piešimas puslapyje ir matavimas išdėstymui
Kiekvienas čia parodytas iškvietimas piešia tiesiai į pasirinkto puslapio turinį – tą patį paviršių, kuriame atvaizduojamas jūsų tekstas ir vaizdai, todėl brūkšninis kodas yra kuriamas įprasto dokumento generavimo metu, o ne importuojamas kaip atskiras elementas. Kadangi simboliai yra vektoriniai, jų koduojami duomenys ir užimama geometrija yra žinomi piešimo metu, kas leidžia juos išdėstyti visiškai tiksliai.
Linijinių šeimų išdėstymui naudinga iš anksto atlikti matavimus. GetBarcodeWidth grąžina bendrą brūkšninio kodo plotį pagal nurodytą siaurojo brūkšnelio plotį ir tipą, todėl galite rezervuoti tikslią horizontalią vietą dar prieš atlikdami piešimą, užuot spėlioję ir pastebėję persidengimą jau sukurtame puslapyje. 2D simbolius išdėstyti paprasčiau, nes nustatote jų piešiamą dydį tiesiogiai per SymbolSize arba ModuleSize, ir simbolis užpildo šį plotą. Bet kuriuo atveju taisyklė ta pati: nustatykite fizinį dydį pagal nuskaitymo aplinką, įsitikinkite, kad simbolis telpa jam skirtoje vietoje, ir leiskite vektorinei geometrijai išlaikyti kiekvieną kraštą aštrų nuo ekrano peržiūros iki galutinio spaudinio.
For the broader page-building workflow these barcodes drop into, the techniques in our article on text, image, and font extraction cover reading content back out of a PDF, and the guide to large PDF merge and split with direct access shows how to assemble high-volume documents efficiently. Both pair naturally with the drawing API described here, which ships as part of the Delphi PDF Library for Delphi and C++Builder alongside the text, graphics, form, and signature APIs covered elsewhere on this blog.