|
|
Vonalkód készítő komponens
Vonalkód 1. rész
|
|
Példaprogram letöltése
10674 bájt
|
Manapság ha megnézünk egy terméket, mondjuk egy bevásárlóközpontban, szinte biztos, hogy találunk rajta egy vonalkódot. Ez a viszonylag logikátlannak tűnő vonalsor tartalmazza a termék egyedi azonosítóját, ami alapján például a pénztárnál is azonosítják a terméket. Ha olyan alkalmazást készítünk, ami ilyen termékeket tart nyilván, akkor szükségünk lehet arra, hogy a termék kódjából vonalkódot készítsünk.
Most készítünk egy olyan komponenst, ami képes egy kódszámból a vonalkód képét előállítani.
A mellékelt példaprogram megnyitása előtt a BarCode.pas-ban lévő komponenst telepítenie kell a Delphi alá.
Először talán mélyedjünk el egy kicsit a vonalkód rejtelmeiben. Azt már rögtön az elején illik tisztázni, hogy egy vonalkódban nem a fekete, hanem a fehér terület a hasznos terület, hiszen a leolvasó ezt tudja csak érzékelni.
A vonalkódoknak többféle típusa létezik, de a legelterjedtebb talán az EAN-13 és EAN-8 kód (EAN = Europaische Artikel Numerierung, Európai árucikkszámozás). Az előbbi 13 számjegyet, míg az utóbbi csak 8 számjegyet kódol.
Először az EAN-13 kódolást vizsgáljuk meg. Ha jól megnézünk egy ilyen vonalkódot, akkor láthatjuk, hogy a baloldalon áll egy szám egymagában, utána pedig 6-6 szám. A szám csoportok között két-két elválasztó vonal van. Ezek a vonalak egy egységnyi vastagságúak. Minden számot két vonallal jelölnek, ezek vastagsága és helye változó. Mint majd látni fogjuk, a számokat összesen hét egységnyi területen kell ábrázolni. Az első számhoz nem tartozik vonal, ez speciálisan van kódolva.
Ha valaki megpróbálja a vonalakból kitalálni, hogy melyik számhoz milyen vonalak tartoznak, akkor hamar abba is hagyja, méghozzá valószínűleg csalódottan. Ez abból adódik, hogy az első 7 szám és az utolsó 6 másféle kódolással van megoldva. Ráadásul az első csoporton belül is lehetnek eltérések az azonos számjegyek kódolása között. Összesen háromféle kódolás van egy vonalkódon belül, ezeket jelöljük A-nak, B-nek és C-nek.
Szám A B C
0 0001101 0100111 1110010
1 0011001 0110011 1100110
2 0011001 0011011 1101100
3 0111101 0100001 1000010
4 0100011 0011101 1011100
5 0110001 0111001 1001110
6 0101111 0000101 1010000
7 0111011 0010001 1000100
8 0110111 0001001 1001000
9 0001011 0010111 1110100
Ha valaki jól megnézi a kódokat, akkor találhat összefüggéseket, de most ezzel nem foglalkozunk. Az első 6 számjegy (a különálló baloldali számot most nem számoljuk!) az A és B, míg az utolsó 6 számjegy a C oszlop szerint van kódolva. Az utolsó 6 számjegy kódolása nem ütközhet különösebb nehézségekbe, de mi van az első 6 számjeggyel? Honnan tudjuk eldönteni, hogy melyik számjegyet melyik oszlop szerint kell kódolni, valamint az első, különálló számjegy hogyan lesz kódolva? Ehhez megint szükségünk lesz egy táblázatra:
Első számjegy Kódolás módja
0 AAAAAA
1 AABABB
2 AABBAB
3 AABBBA
4 ABAABB
5 ABBAAB
6 ABBBAA
7 ABABAB
8 ABABBA
9 ABBABA
A 8 számjegyes vonalkód ettől abban különbözik, hogy az első négy számjegy az A, míg a második négy a C oszlop szerint van kódolva.
Már első látásra is nyilvánvaló, hogy ezeket a táblázatokat konstans tömbökben érdemes tárolni. A fenti táblázat adatait fel lehet úgy is fogni, mint egy 7 bites bináris szám, és így is fogjuk kezelni. Ahol a bit 1, oda húzunk vonalat, ahol 0, oda értelemszerűen nem.
Az első táblázat tehát így néz ki:
CodePage:array[0..9,0..2] of byte =
(($0D,$27,$72), { 0 }
($19,$33,$66), { 1 }
($13,$1B,$6C), { 2 }
($3D,$21,$42), { 3 }
($23,$1D,$5C), { 4 }
($31,$39,$4E), { 5 }
($2F,$05,$50), { 6 }
($3B,$11,$44), { 7 }
($37,$09,$48), { 8 }
($0B,$17,$74)); { 9 }
Mint látható, ez egy kétdimenziós tömb, és ez így tökéletesen használható is lesz számunkra. A fenti 0-kat és 1-eket átszámítottuk 16-os számrendszerbe! A második táblázat úgy néz ki, hogy az egyes számjegyekhez és pozíciókhoz tartozó kódolást egy-egy számmal jelöljük. Az A kódolás 0, a B=1 és a C=2.
CodeEAN13:array[0..9,0..11] of byte =
((0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2), { 0 }
(0, 0, 1, 0, 1, 1, 2, 2, 2, 2, 2, 2), { 1 }
(0, 0, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2), { 2 }
(0, 0, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2), { 3 }
(0, 1, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2), { 4 }
(0, 1, 1, 0, 0, 1, 2, 2, 2, 2, 2, 2), { 5 }
(0, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2), { 6 }
(0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2), { 7 }
(0, 1, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2), { 8 }
(0, 1, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2)); { 9 }
Most nézzük, hogy milyen property-ket kell létrehoznunk. Az első természetesen a kódszámot tartalmazó property, ami 13 vagy 8 karakter hosszú lehet, attól függően, hogy a CodeType property-ben milyen vonalkód típust adtunk meg. Ez utóbbi kétféle lehet: bcEAN13 és bcEAN8. Megadhatjuk továbbá a vonalkód méretét. Ezt két property-vel szabályozhatjuk. Az egyik a LineWidth, amiben a vonalak vastagságát adhatjuk meg pixelben. Ennek értéke a vonalkód képének nagyságát nagyban befolyásolja. Például ha a vonalvastagság 2, akkor az elkészített kép pontosan kétszerese lesz az 1-szeres vonalvastagsággal elkészített képnek. A másik property, ami a méretet befolyásolja, az a Height property. Ebben egy számot adhatunk meg 20 és 80 között. Ez a szélesség és magasság arányát határozza meg százalékosan. Tehát ha 50-et adunk meg, akkor a kép magassága pontosan fele lesz a szélességének. Az elkészült vonalkód képe a Bitmap property-ből kérdezhető le. Az elkészült képet a CopyToClipboard eljárással akár a vágólapra is másolhatjuk.
A vonalkódok elkészítését a MakeBarCode belső eljárás végzi, amely a CodeType property értékétől függően meghívja a MakeEAN13 vagy MakeEAN8 eljárásokat. Van még egy eljárás, a DrawLine, ami a megadott pozícióba rajzol egy vonalat a megfelelő vonalvastagsággal.
A vonalkód megrajzolása viszonylag bonyolult feladat, de csak első pillantásra.
procedure TBarCode.MakeEAN13;
var cmode:0..9;
cbit, bit, i, num, bitcode, xpos:byte;
cw, tx, ty:integer;
begin
Beállítjuk a készítendő kép szélességét és magasságát, valamint a színmélységet. Mivel egy fekete-fehér képről van szó, ezért elég az 1 bites színmélység.
with FBitmap do begin
Width:=FLineWidth*108;
Height:=Round(Width*(FHeight/100));
PixelFormat:=pf1bit;
Dormant;
Töröljük a képet, majd beállítjuk a betűtípust és méretet.
canvas.Brush.Style:=bsSolid;
canvas.Brush.Color:=clWhite;
canvas.FillRect(Rect(0, 0, Width, Height));
canvas.Font.Name:='Arial';
canvas.Font.Height:=FLineWidth*12;
canvas.Font.Color:=clBlack;
A három elválasztó vonalat megrajzoljuk a megfelelő pozíciókba. A DrawLine eljárás második paramétere egy logikai érték, ami azt határozza meg, hogy hosszú vonalat, vagy rövidebben kell húzni. A hosszabb vonalak az elválasztó vonalak, míg a rövidebbek a számokat jelképező vonalak.
DrawLine(7, True);
DrawLine(9, True);
DrawLine(53, True);
DrawLine(55, True);
DrawLine(99, true);
DrawLine(101, True);
Az első számjegyet eltároljuk a cmode változóba. Az xpos változóba az aktuális vonalpozíciót tároljuk. A ty változó a számok y koordinátája, a cw pedig 7 vonal (vagy egy számjegy) kódolásához szükséges terület szélessége pixelben. Az első számot mindjárt ki is írhatjuk.
cmode:=ord(FBarCode[0])-48;
xpos:=10;
ty:=height-canvas.TextHeight('0');
cw:=7*FLineWidth;
Canvas.TextOut(0, ty, FBarCode[0]);
Végigmegyünk a 2. számtól a 12-ig.
A num változóban eltároljuk az i. számot. A bitcode változóba kiolvassuk a CodePage táblázatból a számot jelképező vonalak bitkódját, majd a következő ciklusban (bit) azokba a pozíciókba, ahol 1-es bitet találunk, húzunk egy vonalat.
num:=ord(FBarCode[i])-48;
bitcode:=CodePage[num, CodeEAN13[cmode, i-1]];
cbit:=64;
for bit:=1 to 7 do begin
if (bitcode and (cbit))>0 then DrawLine(xpos, False);
cbit:=cbit div 2;
inc(xpos);
end;
Ha megrajzoltuk a számot jelképező vonalakat, akkor megjelenítjük a számot is.
with Canvas do begin
tx:=(xpos*FLineWidth-cw)+(cw div 2)-
(TextWidth(FBarCode[i]) div 2);
Pen.Color:=clBlack;
TextOut(tx, ty, FBarCode[i]);
end;
A második 6-os csoportot 5 pozícióval jobbra kell kezdeni, hiszen középen is van egy dupla választóvonal, amely 5 pozíciót foglal el.
if i=6 then inc(xpos, 5);
end;
end;
end;
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 235. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|