Tehnički članak

Barkodovi u PDF-u s Delphi-jem: QR, PDF417, DataMatrix

Barkod na otpremnoj naljepnici ili računu ima jedan zadatak, a to je da ga skener očita iz prvog pokušaja. Hoće li preživjeti taj pokušaj odlučuje se mnogo prije nego što paket stigne na utovarnu rampu. Odlučuje se načinom na koji je simbol postavljen na stranicu. Najčešća pogreška u Delphi cjevovodu za izvještavanje je renderiranje barkoda kao bitmape negdje drugdje i postavljanje te slike u PDF. Izgleda dobro na zaslonu na jednoj razini zumiranja, a zatim degradira svugdje drugdje

Alternativa je crtanje simbola kao vektorskog sadržaja, izravno na stranicu. PDF Library for Delphi izlaže obitelj poziva za crtanje upravo za to, pokrivajući 2D matrične simbole QR, PDF417 i DataMatrix, linearne obitelji kroz Code128 i GS1-128, te USPS Intelligent Mail za poštansku automatizaciju. Argument za vektore nije estetski. Radi se o tome hoće li linije sletjeti tamo gdje skener očekuje

Zašto vektor pobjeđuje postavljenu bitmapu

Barkod je uzorak linija i razmaka, ili u dvije dimenzije mreža tamnih i svijetlih modula. Dekoder radi mjerenjem omjera tih širina. Sve što iskrivljuje omjere je šum koji troši proračun pogrešaka simbola. Rasterizirana slika barkoda nosi fiksne piksele. Kada se PDF iscrtava na pisaču čije se točke ne dijele ravnomjerno u mrežu slike, rasterizator mora ponovno uzorkovati, a rubovi modula koji bi trebali biti oštri šire se na dva piksela uređaja. Uska linija može se podebljati, susjedni prostor stanjiti, a omjer širine na koji se dekoder oslanja pluta

Nacrtan kao vektorski sadržaj, isti simbol je skup ispunjenih pravokutnika opisanih u koordinatama korisničkog prostora PDF-a. Nema fiksne mreže piksela s kojom se treba boriti. Prilikom ispisa, uređaj iscrtava svaki pravokutnik u rezoluciji koju stvarno ima, tako da je svaki rub modula oštar onoliko koliko hardver dopušta, u bilo kojem mjerilu i bilo kojoj veličini ispisa. Povećajte vektorski simbol za paletnu naljepnicu ili ga smanjite za paket i geometrija ostaje točna. Ta preciznost je ono što održava visoku stopu čitanja iz prvog pokušaja, što je i smisao postavljanja barkoda na stranicu

PDF Library for Delphi dijagram koji uspoređuje crtični kod iz bitmape zamagljen ispisničkim ponovnim uzorkovanjem s vektorskim pravokutnicima koji rubove modula čuvaju oštrima pri svakoj veličini ispisa
Trake resamplirane bitmape odstupaju od kodiranih omjera širina

QR kodovi i četiri razine ispravka

QR je 2D matrični simbol koji se čita u obje osi odjednom, zbog čega pakira puno podataka u mali kvadrat. Njegova tolerancija na oštećenja dolazi od Reed-Solomonove korekcije pogrešaka, ponuđene na četiri razine. Razina L oporavlja otprilike 7 posto kodnih riječi, M oko 15 posto, Q oko 25 posto, a H oko 30 posto. Viša razina korekcije nije besplatna. Kodne riječi za oporavak zauzimaju kapacitet modula, pa za fiksnu količinu podataka viša razina nameće gušći ili fizički veći simbol

Kompromis je pitanje o okruženju u kojem će simbol živjeti. Čist digitalni dokument koji će se skenirati samo sa zaslona može ostati na razini L i biti kompaktan. Naljepnica koja će se ispisivati, držati u rukama, strugati i možda djelomično prekriti trakom zahtijeva Q ili H, jer je dodatna redundantnost ono što omogućuje dekoderu da rekonstruira korisni teret iz simbola koji više nije besprijekoran. DrawQRCode uzima poziciju i SymbolSize koji fiksira nacrtanu širinu i visinu, plus vrijednost EncodeOptions koja odabire način rada podataka (0 za automatski, ili numeričke, alfanumeričke, ISO-8859-1 i UTF-8 varijante) i vrijednost DrawOptions za orijentaciju

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;

Samu razinu korekcije odabire enkoder kako bi podatke uklopio u simbol koji ste tražili. Ako vam je potrebna zajamčena visoka razina za grubo okruženje, velikodušno odaberite veličinu simbola tako da enkoder ima dovoljno prostora za redundantnost umjesto da bude prisiljen smanjiti je radi uklapanja

PDF417 za ID-ove i naljepnice za otpremu

PDF417 je složeni linearni simbol. Svaki red je kratki linearni barkod, a redovi se slažu kako bi stvorili blok, zbog čega se pojavljuje na vozačkim dozvolama, ukrcajnim propusnicama i otpremnim naljepnicama prijevoznika gdje širi niz podataka mora sjediti u pravokutnom obliku. Njegova korekcija pogrešaka kreće se na ljestvici od 0 do 8. Svaki korak otprilike udvostručuje broj kodnih riječi za ispravak, tako da razina 5 nosi daleko više redundantnosti od razine 1, pod cijenu više kodnih riječi na stranici

Oblik bloka PDF417 je prilagodljiv, a to je važno jer naljepnica ima fiksno područje za popunjavanje. DrawPDF417SymbolEx izlaže kontrole koje osnovni poziv nema. FixedColumns i FixedRows fiksiraju broj stupaca podataka i broj redaka, pri čemu 0 znači da enkoder sam odlučuje. ErrorLevel uzima -1 za automatski ili eksplicitno 0 do 8. ModuleSize je širina najužeg elementa u trenutnoj mjernoj jedinici, a HeightWidthRatio postavlja koliko je svaki modul visok u odnosu na svoju širinu, što je način na koji blok činite kratkim i širokim ili visokim i uskim kako bi odgovarao prostoru koji imate

// Fixed 10 data columns, automatic rows, error level 5,
// modul širine 0.30 mm, retci su visoki tri širine modula
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 u trenutačnoj mjernoj jedinici
  3.0);     // HeightWidthRatio

Fiksiranje stupaca je uobičajena poluga na predlošku naljepnice. Konstantan broj stupaca daje bloku predvidljivu širinu, tako da se okolni izgled ne pomiče kako kodirani korisni teret mijenja duljinu od jednog dokumenta do drugog, dok enkoder dodaje redove prema dolje kako bi apsorbirao razliku

DataMatrix za male oznake

DataMatrix je simbol za kojim treba posegnuti kada oznaka mora biti mala. To je kompaktna 2D mreža koja koristi ECC 200, modernu Reed-Solomonovu shemu, i ostaje čitljiva na veličinama na kojima bi QR simbol istih podataka bio nespretan. To ga čini standardnim izborom za izravno označavanje dijelova, male elektroničke komponente i guste logističke naljepnice

PDF Library for Delphi dijagram razina ispravljanja pogrešaka QR kodova L, M, Q i H koje oporavljaju otprilike 7, 15, 25 i 30 posto kodnih riječi uz rastući trošak modula
Više razine Reed-Solomon oporavljaju više oštećenih kodnih riječi, ali troše kapacitet modula

DrawDataMatrixSymbol uzima ModuleSize za korak točke, Encoding s vrijednošću 1 za ASCII i SymbolSize koji je ili 0 za automatski ili jedna od standardnih kvadratnih i pravokutnih dimenzija, od 10x10 do 132x132. Parametar Options kombinira orijentaciju sa širinom mirne zone, gdje dodavanje 100 do 400 postavlja bijeli obrub od jednog do četiri modula. Mirna zona nije ukras. Dekoder treba tu čistu marginu kako bi pronašao uzorak pronalazača simbola, a simbol stiješnjen uz drugu tintu je simbol koji se ne uspijeva očitati

// Automatski određeni ASCII DataMatrix, modul 0.5 mm, normalna orijentacija
// s jednom modulskom zaštitnom zonom (Options 0 + 100)
Pdf.DrawDataMatrixSymbol(20, 110, 0.5, 'DMX-SN-4408812',
  1,        // Encoding: 1 = ASCII
  0,        // SymbolSize: 0 = automatic
  100);     // Options: normalno + zaštitna zona širine jednog modula

Gdje 1D barkodovi i dalje vladaju

Dvodimenzionalni simboli privlače pozornost, ali linearni barkodovi i dalje posjeduju velike dijelove maloprodaje i logistike, a razlog je instalirana baza laserskih skenera koji čitaju jednim prelaskom. Code128 je radni konj za alfanumeričke podatke, a njegova učinkovitost dolazi iz tri skupa znakova. Skup A pokriva kontrolne znakove i velika slova, skup B pokriva cijeli ispisivi ASCII raspon, a skup C je onaj koji je važan za brojeve. Podskup C kodira par znamenki u jednom znaku simbola, tako da niz numeričkih podataka zauzima upola manje znakova simbola nego što bi u skupu A ili B. To je najkompaktniji način za postavljanje dugog numeričkog barkoda, a PDF Library for Delphi implementacija Code128 automatski kombinira skupove B i C kako bi ga postigla

GS1-128, standard ranije nazvan EAN-128, nadograđuje se na Code128 noseći aplikacijske identifikatore, prefikse u zagradama koji primateljskom sustavu govore jesu li sljedeće znamenke serijski broj, šifra serije ili datum isteka valjanosti. Struktura je označena s FNC1, posebnim nepodatkovnim znakom koji označava simbol kao GS1-kodiran i razdvaja polja varijabilne duljine. U PDF Library for Delphi-u crtate GS1-128 simbol pomoću DrawBarcode koristeći tip Code128 i literalni marker [FNC1] postavljen u niz podataka gdje počinje svaki aplikacijski identifikator

PDF Library for Delphi dijagram koji GS1-128 podatkovni niz razlaže na FNC1 oznake, aplikacijski identifikator 21 za serijski broj i aplikacijski identifikator 20 za varijantu
FNC1 markeri označavaju simbol kao GS1 i zatvaraju svako polje promjenjive duljine
var
  W: Double;
begin
  // Code128, s oznakama FNC1 postaje simbol GS1-128
  // 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

  // Izmjeri renderiranu širinu uske trake od 0.30 mm prije raspoređivanja
  W := Pdf.GetBarcodeWidth(0.30, '[FNC1]21ABC123[FNC1]2013', 3);
end;

Za poštu, USPS Intelligent Mail, također nazvan OneCode, kodira podatke o usmjeravanju i praćenju u jednom barkodu moduliranom visinom za poštansku automatizaciju. DrawIntelligentMailBarcode uzima eksplicitnu geometriju za širinu linije, punu visinu linije, visinu tragača i širinu prostora, s podacima koji se dostavljaju kao niz od 20, 25, 29 ili 31 znamenke. Eksplicitne visine linije i tragača postoje jer simbol nosi informacije o tome je li svaka linija puna, uzlazna ili silazna, a poštanski čitač ovisi o tome drže li se te visine specifikacija

Praktični kontekst

Svaki ovdje prikazani poziv crta u sadržaj trenutno odabrane stranice, istu površinu koja prima vaš tekst i slike, tako da se barkod proizvodi kao dio uobičajenog generiranja dokumenta, a ne uvozi kao zaseban resurs. Budući da su simboli vektorski sadržaj, podaci koje kodiraju i geometrija koju zauzimaju poznati su u trenutku crtanja, što vam omogućuje da ih postavite deterministički

Izgled linearnih obitelji ima koristi od prethodnog mjerenja. GetBarcodeWidth vraća ukupnu nacrtanu širinu barkoda za zadanu širinu uske linije i tip barkoda, tako da možete rezervirati točan vodoravni prostor prije nego što izvršite crtanje, umjesto nagađanja i otkrivanja preklapanja nakon što se stranica izgradi. 2D simbole je jednostavnije postaviti jer njihovu nacrtanu veličinu postavljate izravno putem SymbolSize ili ModuleSize, i simbol popunjava taj otisak. U svakom slučaju, disciplina je ista. Odredite fizičku veličinu na temelju okruženja skeniranja, potvrdite da simbol stane u utor koji imate i dopustite vektorskoj geometriji da održi svaki rub oštrim od pregleda na zaslonu do konačnog ispisa

Za širi tijek rada izgradnje stranica u koji se ovi barkodovi uklapaju, tehnike u našem članku o ekstrakciji teksta, slika i fontova pokrivaju čitanje sadržaja natrag iz PDF-a, a vodič za spajanje i dijeljenje velikih PDF-ova s izravnim pristupom pokazuje kako učinkovito sastaviti dokumente velikog volumena. Obje se prirodno povezuju s API-jem za crtanje koji je ovdje opisan, a koji se isporučuje kao dio softvera Delphi PDF Library za Delphi i C++Builder, zajedno s API-jima za tekst, grafiku, obrasce i potpis koji su pokriveni drugdje na ovom blogu