Баркодът върху етикет за доставка или фактура има една задача, и тя е да бъде разчетен от скенер от първия път. Дали ще премине успешно този опит, се решава много преди пакетът да достигне до склада. Решава се от начина, по който символът е бил поставен върху страницата. Най-честата грешка в тръбопровод за отчети в Delphi е баркодът да се рендира като растерно изображение на друго място и това изображение да се постави в PDF файла. Изглежда добре на екрана при едно ниво на мащабиране и след това качеството му се влошава навсякъде другаде.
Алтернативата е символът да се начертае като векторно съдържание, директно на страницата. PDFlibPas предлага фамилия от функции за изчертаване точно за това, покриващи 2D матричните символи QR, PDF417 и DataMatrix, линейните фамилии чрез Code128 и GS1-128, както и USPS Intelligent Mail за пощенска автоматизация. Аргументът в полза на векторите не е естетически. Той е свързан с това дали лентите попадат там, където скенерът ги очаква.
Защо векторното изчертаване превъзхожда поставеното растерно изображение
Баркодът е модел от ленти и интервали, а в две измерения – решетка от тъмни и светли модули. Декодерът работи чрез измерване на съотношението на тези ширини. Всичко, което изкривява съотношенията, е шум, който изяжда лимита за грешки на символа. Растеризираното изображение на баркод съдържа фиксирани пиксели. Когато PDF файлът се рендира на принтер, чиито точки не се делят равномерно на решетката на изображението, растеризаторът трябва да пренабере проби (resample) и краищата на модулите, които трябва да са остри, се разпределят върху два пиксела на устройството. Тясна лента може да се разшири, съседен интервал може да се стесни и съотношението на ширината, на което разчита декодерът, се измества.
Начертан като векторно съдържание, същият символ е набор от запълнени правоъгълници, описани в PDF координати на потребителското пространство. Няма фиксирана пикселна решетка, с която да се борите. По време на печат устройството рендира всеки правоъгълник с разделителната способност, която действително притежава, така че всеки ръб на модула е толкова остър, колкото позволява хардуерът, при всякакъв мащаб и размер на печат. Увеличете мащаба на векторен символ за палетен етикет или го намалете за колет и геометрията остава точна. Тази прецизност е това, което поддържа висок процента на четене от първия път, което е и смисълът от поставянето на баркод на страницата.
QR кодове и четирите нива на корекция
QR е 2D матричен символ, който се чете и по двете оси едновременно, поради което събира много данни в малък квадрат. Неговата устойчивост на повреди идва от Reed-Solomon корекцията на грешки, предлагана на четири нива. Ниво L възстановява приблизително 7 процента от кодовите думи, M – около 15 процента, Q – около 25 процента, и H – около 30 процента. По-високата корекция не е безплатна. Кодовите думи за възстановяване заемат капацитет от модули, така че при фиксирано количество данни по-високото ниво налага по-плътен или физически по-голям символ.
Компромисът зависи от средата, в която ще съществува символът. Чист дигитален документ, който ще се сканира само от екран, може да бъде с ниво L и да остане компактен. Етикет, който ще бъде отпечатан, обработван, надраскан и вероятно частично покрит с тиксо, изисква Q или H, тъй като допълнителната излишност е това, което позволява на декодера да възстанови полезния товар от символ, който вече не е непокътнат. DrawQRCode приема позицията и SymbolSize, които определят начертаната ширина и височина, плюс стойност EncodeOptions, която избира режима на данни (0 за автоматично, или цифрови, буквено-цифрови, ISO-8859-1 и UTF-8 варианти), и стойност DrawOptions за ориентация.
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;
Самото ниво на корекция се избира от енкодера, за да съответства на данните в символа, който сте поискали. Ако имате нужда от гарантирано високо ниво за тежка среда, оразмерете символа щедро, така че кодиращият механизъм да разполага с бюджет от модули за излишност, вместо да бъде принуден да го сбие, за да се побере.
PDF417 за лични карти и етикети за доставка
PDF417 е подреден линеен символ. Всеки ред е кратък линеен баркод и редовете се подреждат, за да образуват блок, поради което се появява на шофьорски книжки, бордови карти и транспортни етикети, където по-широка лента с данни трябва да се побере в правоъгълно пространство. Неговата корекция на грешки работи по скала от 0 до 8. Всяка стъпка грубо удвоява броя на кодовите думи за корекция, така че ниво 5 носи много по-голяма излишност от ниво 1, за сметка на повече кодови думи на страницата.
Формата на блока PDF417 се регулира и това има значение, тъй като етикетът има фиксирана област за запълване. DrawPDF417SymbolEx разкрива контролите, които базовото извикване не разкрива. FixedColumns и FixedRows фиксират броя на колоните и редовете с данни, като 0 означава да се остави на кодиращия механизъм да реши. ErrorLevel приема -1 за автоматично или явно 0 до 8. ModuleSize е ширината на най-тесния елемент в текущата мерна единица, а HeightWidthRatio определя колко висок е всеки модул спрямо ширината си, което е начинът да направите блока къс и широк или висок и тесен, за да съответства на пространството, с което разполагате.
// 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
Фиксирането на колони е обичайният инструмент в шаблона за етикети. Постоянният брой колони дава на блока предвидима ширина, така че околното оформление да не се измества, когато кодираният полезен товар променя дължината си от един документ към друг, докато кодиращият механизъм добавя редове надолу, за да абсорбира разликата.
DataMatrix за малки маркировки
DataMatrix е символът, към който да посегнете, когато маркировката трябва да е малка. Това е компактна 2D решетка, която използва ECC 200 – модерната схема на Reed-Solomon, и остава четима при размери, при които QR символ със същите данни би бил твърде голям. Това я прави стандартен избор за директна маркировка на части, малки електронни компоненти и плътни логистични етикети.
DrawDataMatrixSymbol приема ModuleSize за размера на точката, Encoding със стойност 1 за ASCII и SymbolSize, което е 0 за автоматично или един от стандартните квадратни и правоъгълни размери, от 10x10 до 132x132. Параметърът Options комбинира ориентацията с ширината на тихата зона (quiet-zone), където добавянето на 100 до 400 задава бяла граница от един до четири модула. Тихата зона не е декорация. Декодерът се нуждае от това свободно поле, за да намери опорната точка на символа, а символ, притиснат до друго мастило, е символ, който не може да бъде разчетен.
// 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
Къде линейните 1D баркодове все още доминират
Двуизмерните символи привличат вниманието, но линейните баркодове все още притежават големи части от търговията на дребно и логистиката, и причината за това е внедрената база от лазерни скенери, които четат с едно преминаване. Code128 е работният кон за буквено-цифрови данни и неговата ефективност идва от три набора от знаци. Набор A обхваща контролни знаци и главни букви, набор B обхваща пълния диапазон от ASCII знаци за печат, а набор C е този, който има значение за числата. Подмножество C кодира двойка цифри в един символен знак, така че поредица от цифрови данни заема половината от символните знаци, които би изисквала в набор A или B. Това е най-компактният начин за поставяне на дълъг цифров баркод и имплементацията на Code128 в PDFlibPas комбинира автоматично наборите B и C, за да го постигне.
GS1-128, стандартът, наричан по-рано EAN-128, се базира на Code128, като пренася идентификатори на приложения (Application Identifiers) – префиксите в скоби, които казват на приемащата система дали следващите цифри са сериен номер, код на партида или срок на годност. Структурата е маркирана с FNC1, специален незнаков знак, който обозначава символа как GS1-кодиран и разделя полетата с променлива дължина. В PDFlibPas вие чертаете GS1-128 символ с DrawBarcode, използвайки типа Code128 и буквения маркер [FNC1], поставен в низа с данни, където започва всеки идентификатор на приложение.
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;
За пощенски пратки, USPS Intelligent Mail, наричан още OneCode, кодира данни за маршрутизиране и проследяване в един баркод с модулирана височина за пощенска автоматизация. DrawIntelligentMailBarcode приема изрична геометрия за ширината на лентата, пълната височина на лентата, височината на тракера и ширината на пространството, като данните се предоставят като низ от само 20, 25, 29 или 31 цифри. Изричните височини на лентите и тракера съществуват, тъй като символът носи информация за това дали всяка лента е пълна лента, възходяща или низходяща, а пощенският четец зависи от това тези височини да съответстват на спецификацията.
Изчертаване в страницата и измерване за оформление
Всяко извикване, показано тук, рисува в съдържанието на текущо избраната страница, същата повърхност, която приема вашия текст и изображения, така че баркодът се произвежда като част от нормалното генериране на документи, а не се импортира като отделен ресурс. Тъй като символите са векторно съдържание, данните, които кодират, и геометрията, която заемат, са известни по време на изчертаването, което ви позволява да ги разположите детерминистично.
Оформлението за линейните семейства се улеснява от предварително измерване. GetBarcodeWidth връща общата начертана ширина на баркода за дадена ширина на тясната лента и тип баркод, така че можете да резервирате точното хоризонтално пространство, преди да се ангажирате с чертането, вместо да гадаете и да откривате застъпване след изграждането на страницата. 2D символите са по-лесни за поставяне, тъй като задавате техния начертан размер директно чрез SymbolSize или ModuleSize, и символът запълва тази площ. И в двата случая дисциплината е същата. Решете физическия размер въз основа на средата за сканиране, потвърдете, че символът се побира в слота, който имате, и оставете векторната геометрия да поддържа всеки ръб остър – от прегледа на екрана до крайния печат.
За по-широкия работен процес за изграждане на страници, в който се включват тези баркодове, техниките в нашата статия за извличане на текст, изображения и шрифтове обхващат четенето на съдържание обратно от PDF файл, а ръководството за сливане и разделяне на големи PDF файлове с директен достъп показва как да сглобявате документи с голям обем ефективно. И двете се комбинират по естествен начин с API за чертане, описан тук, който се доставя като част от Delphi PDF Library за Delphi и C++Builder, заедно с API за текст, графика, формуляри и подписи, разгледани на други места в този блог.