HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

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.
    for i:=1 to 12 do begin
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;


Cikksorozat

#IDKategóriaCikk címeSorozat
3333WindowsNet Shell parancsok1. rész
3367WindowsNet Shell parancsok2. rész
3396WindowsNet Shell parancsok3. rész


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!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |