P R O G R A M U J E M ECREATE TABLE Rubriky(id_rubriky INT NOT NULL PRIMARY KEY,<strong>na</strong>zov VARCHAR(20),statistika INT);CREATE TABLE Clanky(id_clanku INT NOT NULL PRIMARY KEY,id_autora INT NOT NULL,id_rubriky INT NOT NULL,datum DATE,<strong>na</strong>zov VARCHAR(50),anotacia VARCHAR(250),text LONG,obrazok VARCHAR(30),statistika INT);CREATE SEQUENCE id_clanku INCREMENT BY 1;Za zmienku stojí deklarácia text LONG, typ LONG v Oracle 8i umožòuje zadáva re azceaž do dåžky 2 31 z<strong>na</strong>kov.MS SQL Server 2000CREATE TABLE Autori(id_autora INT PRIMARY KEY,priezvi<strong>sk</strong>o VARCHAR(15),meno VARCHAR(15),heslo VARCHAR(8),email VARCHAR(15),statistika INT);CREATE TABLE Rubriky(id_rubriky INT PRIMARY KEY,<strong>na</strong>zov VARCHAR(20),statistika INT);CREATE TABLE Clanky(id_clanku INT IDENTITY (1, 1) NOT FOR REPLICATION PRIMARY KEY,id_autora INT NOT NULL,id_rubriky INT NOT NULL,datum DATETIME,<strong>na</strong>zov VARCHAR(50),anotacia VARCHAR(250),text TEXT,obrazok VARCHAR(30),statistika INT);Aby sme mohli zaèa vývoj a hlavne ladenie <strong>sk</strong>riptového kódu, musíme <strong>na</strong>plni tabu¾kyhodnotami potrebnými <strong>na</strong> zobrazenie minimálne jedného èlánku. Keïže tabu¾ky Autori,Rubriky a Clanky sú vzájomne relaène zviazané, musíme ich <strong>na</strong>plni každú aspoòjedným záz<strong>na</strong>mom. Do tabu¾ky Autori vložíme záz<strong>na</strong>m:INSERT INTO AutoriVALUES (1, ‘Kuchtikova’, ‘Beata’, ‘beatka’, ‘b@b.<strong>sk</strong>’, 0);do tabu¾ky Rubriky záz<strong>na</strong>m:INSERT INTO Rubriky VALUES (1, ‘LINIA’, 0);a do tabu¾ky Clanky záz<strong>na</strong>m:INSERT INTO ClankyVALUES (id_clanku.nextval, 1,1, SYSDATE,‘Štíhla línia - sen všetkých dievèat’,‘Ktorá z nás by nechcela by štíhla a prí ažlivá..’,‘...Zaver je prekvapivo jednoduchy: Menej jedla a viac pohybu’,‘beatka.jpg’,0);Pre zobrazenie informácie o èlánku <strong>na</strong> hlavnej stránke publikaèného portálu použijemekombinovaný dopyt SQL do všetkých troch tabuliek:SELECT Rubriky.<strong>na</strong>zov, Autori.priezvi<strong>sk</strong>o, Autori.meno, Clanky.<strong>na</strong>zov, Clanky.anotacia,Clanky.statistikaFROM Rubriky, Autori, ClankyWHERE Clanky.id_rubriky = Rubriky.id_rubriky AND Clanky.id_autora = Autori.id_autora;Ak takýto dopyt SQL zadáme pomocou konzoly databázovému serveru, ten nám vrátipožadovaný výsledok:LINIA Kuchtikova BeataŠtíhla línia - sen všetkých dievèatKtorá z nás by nechcela by štíhla a prí ažlivá.. 0Presne takto sme si predstavovali, že to bude vypísané <strong>na</strong> stránke HTML u klienta,samozrejme, v lepšej úprave. Tento dopyt SQL musíme vyko<strong>na</strong> pomocou <strong>sk</strong>riptovéhokódu <strong>na</strong> stránke ASP a vygenerova stránku HTML pre klienta. Ale o tom až v <strong>na</strong>sledujúcompokraèovaní seriálu.¼uboslav LackoPHP a obrázky / 2. èasV predošlej èasti sme si ukázali, ako je možné vytvára obrázky v pamäti a ako ich odtia¾uvo¾ni . Takisto sme si ukázali, ako obrázky <strong>na</strong>èíta zo súborov rôznych formátov. Tentorazsa budeme venova kresleniu v obrázkoch.KRESLIACE FUNKCIE GD. Základnou jednotkou v obrázku je pixel, a pretozaèneme funkciou <strong>na</strong> <strong>na</strong>stavenie (kreslenie) pixela. Na to nám poslúži funkcia Image-SetPixel(), ktorá vyžaduje štyri argumenty. Prvým je identifikátor obrázka (ktorým smesa zaoberali v predchádzajúcej èasti), v ktorom chcete príslušnú kresliacu funkciu [vtomto prípade ImageSetPixel()] použi . Tento identifikátor je vyžadovaný každou kresliacoufunkciou GD knižnice. Preto vždy pred kreslením musíte vytvori obrázok niektorýmzo spôsobov, ktoré sme uviedli v predošlej èasti, teda buï vytvorením prázdnehoobrázka priamo v <strong>sk</strong>ripte, alebo <strong>na</strong>èítaním zo súboru. Vrá me sa k funkciiImageSetPixel(). Druhým a tretím argumentom je daná pozícia pixela, ktorého farbuchcete <strong>na</strong>stavi , prièom druhý argument predstavuje x-ovú súradnicu a tretí y-ovú. Zapoèiatok sa považuje ¾avý horný roh, ktorý má súradnice [0,0]. Pozícia <strong>na</strong>stavovanéhopixela by logicky nemala prekroèi ani jeden s rozmerov obrázka, pretože hoci <strong>sk</strong>riptnevyvolá nijaké chybové hlásenie, v obrázku ne<strong>na</strong>stanú žiadne zmeny. Poslednýmparametrom funkcie je farba, <strong>na</strong> ktorú má by pixel <strong>na</strong>stavený. Narábaniu s farbamisa budeme venova ne<strong>sk</strong>ôr, teraz iba vedzte, že tento parameter je typu int azvykne sa odovzdáva vo forme premennej, do ktorej si uložíte index farby v palete.Ukážka, ako môžete funkciou ImageSetPixel() <strong>na</strong>príklad vykresli vodorovnú èiaru dlhú10 pixelov:Tento kód vykreslí vodorovnú èiaru od pozície [0,50] po [10,50]. Na <strong>na</strong>stavenie jejfarby treba priradi premennej $cier<strong>na</strong> index príslušnej (v tomto prípade èiernej) farby vpalete. Ako to urobi , to sa dozviete ne<strong>sk</strong>ôr.Predchádzajúci príklad bol síce pekný ako ukážka kreslenia pomocou Image-SetPixel(), ale urèite aj nepraktický. Na kreslenie èiar v obrázkoch je v GD knižnici užpreddefinovaná funkcia ImageLine(). Táto funkcia vám umožní kresli èiary ove¾a pohodlnejšieako predchádzajúca. Prvým parametrom funkcie je opä už spomí<strong>na</strong>ný identifikátorobrázka, v ktorom chcete èiaru <strong>na</strong>kresli . Ïalšie dva parametre urèujú súradnicev obrázku, kde sa bude èiara zaèí<strong>na</strong> , prièom druhý parameter predstavuje x-ovúsúradnicu a tretí y-ovú súradnicu. Ïalšie dva parametre rov<strong>na</strong>kým spôsobom opisujúsúradnice konca èiary. Posledným parametrom je index farby, ktorou bude èiara <strong>na</strong>kreslená.Tento index môže by aj <strong>na</strong>hradený vzorkou štetca, vïaka èomu môžete kresli ajvzorkované èiary. Aby ste tento spôsob vykres¾ovania èiary mohli používa , musíte <strong>na</strong>jprvpríslušný vzor vytvori ako obrázok (je jedno, akým spôsobom, èi si ho vytvoríte a<strong>na</strong>kreslíte sami alebo ho <strong>na</strong>èítate zo súboru) a potom zavola funkciu ImageSetBrush(),ktorej prvým parametrom je identifikátor obrázka, v ktorom chcete daný typ štetcapoužíva , a druhým parametrom je identifikátor obrázka obsahujúci žiadaný štetec.Keïže štetec je tiež iba obyèajným obrázkom, mali by ste ho vždy, keï ho už nebudetepotrebova , uvo¾ni z pamäte. Po uvo¾není z pamäte ho však už nesmiete používa .Nasledujúci príklad vykreslí èiaru od súradnice [10,10] po súradnicu [70,70]. Vzorecštetca je <strong>na</strong>èítaný zo súboru JPG.Musím upozorni , že v prípade, že používate php_gd.dll priamo z distribúcie PHP 4.0.6(samozrejme pod Win32), môžete ma problémy s používaním štetcov. Ak by sa tak staloa vy by ste chceli štetce vo svojich <strong>sk</strong>riptoch používa , musíte si GD knižnicu <strong>sk</strong>ompilovasami. V tom prípade si však pozrite dobre dokumentáciu, pretože názvy funkcií a pre-134 PC REVUE 10/2001
P R O G R A M U J E M Emenných sa v zdrojovom kóde GD knižnice trošku líšia od tých, ktoré sa používajú v PHPa ktoré tu uvádzam ja. Konkrétne sa líšia tým, že majú predponu gd. Preto sa môže líšiposledný parameter odovzdávaný vo funkcii ImageLine() – v zdrojovom kóde GD sapoužíva gdBrushed, nie $Brushed.Typ štetca môžete tiež <strong>na</strong>stavi pomocou funkcie ImageSetStyle(). Tá sa líši od predchádzajúcejtým, že typ štetca nie je <strong>na</strong>stavený iným obrázkom, ale vy môžete priamodefinova , ktoré pixely a akou farbou budú vykreslené. Tento spôsob vykres¾ovaniaèiary je náhradou za zastaraný typ funkcie ImageDashedLine(). Funkcia ImageSetStyle()vyžaduje pod¾a špecifikácie v GD knižnici tri parametre – identifikátor obrázka, poleobsahujúce špecifikáciu pixelov (farby) a posledným je ve¾kos tohto po¾a. Zo <strong>sk</strong>úsenostis dodávanou DLL knižnicou PHP 4.0.6 však viem, že posledný parameter funkcianevyžaduje, je to však iba špecialita tejto verzie GD knižnice. Pri kreslení èiary musítepotom odovzda ako farbu posledný parameter premennú $Styled (gdStyled pod¾ašpecifikácie v dokumentácii). Ako vidíte, <strong>na</strong> zložitejšie kreslenie je GD knižnica dodávanás PHP 4.0.6 distribúciou pre Win32 dos nevhodná.GD knižnica tiež umožòuje kreslenie polygónov. Ide o dvojrozmerné útvary, ktoré súdefinované súradnicami ich vrcholov. Na kreslenie polygónov využijete funkciu Image-Polygon(). Jej prvým parametrom je opä identifikátor obrázka. Ïalším parametrom jepole celoèíselných prvkov, ktoré definujú súradnice jednotlivých bodov. Tieto súradnicemusia by v poli uložené postupne, vždy <strong>na</strong>jprv x-ová súradnica a za òou y-ovásúradnica. Prvým prvkom v poli je x-ová súradnica prvého bodu a druhým prvkom jey-ová súradnica toho istého bodu a tak to pokraèuje ïalej. Matematicky vyjadrené, x-ová súradnica i-teho bodu je uložená v prvku po¾a s indexom [(i-1)*2] a y-ová súradnicav prvku po¾a s indexom [((i-1)*2) + 1]. Pre zjednodušenie uvádzam ukážku – definovaniepo¾a 3 bodov, teda pre polygón s tromi vrcholmi (trojuholník):$body[0] = 10; // prvý bod [10,10]$body[1] = 10;$body[2] = 20; // druhý bod [20,10]$body[3] = 10;$body[4] = 15; // tretí bod [15,20]$body[5] = 20;Ako vidíte, toto riešenie je síce jednoduché, ale dos ažkopádne. V originálnej GDknižnici je táto záležitos riešená pomocou štruktúry gdPoint (o tej ste si mohli preèítaminule), ktorá obsahuje dva atribúty: x a y, teda súradnice bodu. To je urèite lepšieriešenie, keïže poèet bodov je zhodný s poètom prvkov po¾a. Vrá me sa však k parametromfunkcie ImagePolygon(). Tretím parametrom je poèet bodov, ktoré má polygónobsahova . Je to jednoducho poèet prvkov, ktoré sú uložené v poli odovzdávanom akodruhý parameter, takže by to mala by polovica poètu prvkov tohto po¾a, lebo jedenbod zodpovedá práve dvom prvkom v poli. Samozrejme, je možné zada aj menšieèíslo, než je poèet bodov obsiahnutých v poli, èo môžete využi v prípade, že nechcete,aby boli použité všetky body. Táto hodnota nesmie by nižšia ako 3, lebo polygónmá minimálne 3 vrcholy. Posledným parametrom funkcie ImagePolygon() je farba, ktoroubude polygón <strong>na</strong>kreslený (o farbách sa doèítate ne<strong>sk</strong>ôr). Funkcia ImagePolygon()slúži <strong>na</strong> kreslenie nevyplnených polygónov, teda iba <strong>na</strong> kreslenie ich obrysov. Ak chcete,aby bol polygón vyplnený, musíte využi funkciu ImageFilledPolygon(). Špecifikáciaa poèet parametrov tejto funkcie sú úplne rov<strong>na</strong>ké ako ImagePolygon(), rozdiel spoèívaiba v tom, že polygón vykreslený funkciou bude aj vyplnený farbou, špecifikovanouposledným parametrom. Ukážka použitia funkcie ImageFilledPolygon() <strong>na</strong> <strong>na</strong>kreslenievyplneného trojuholníka:Špeciálnym typom polygónu je obdåžnik. Keïže tvorcovia GD knižnice pravdepodobnepredpokladali, že programátori by mohli èasto využíva kreslenie obdåžnikov(resp. štvorcov), pridali do nej funkciu ImageRectangle(). Jej použitie je ve¾mi jednoduché– vždy jej musíte ako prvý argument odovzda identifikátor obrázka, v ktoromchcete obdåžnik vykresli . Ïalšími parametrami sú x-ová súradnica a y-ová súradnica¾avého horného rohu obdåžnika, ktorý chcete vykresli , a za nimi <strong>na</strong>sledujú súradnicepravého dolného rohu obdåžnika v rov<strong>na</strong>kom poradí: <strong>na</strong>jprv x-ová a potom y-ová súradnica.Posledným parametrom funkcie je farba rámu obdåžnika. Jednotlivé súradnicevykres¾ovaného obdåžnika, samozrejme, nesmú prekraèova hranice obrázka a ani bymenšie ako 0. Ak sa tak stane, vykreslí sa iba èas obdåžnika, ktorá sa zmestí <strong>na</strong> obrázok.Funkcia ImageRectangle() vykres¾uje iba rám obdåžnika, prièom jeho vnútro zostávanezmenené. To je vlastne ekvivalentom štvornásobného volania funkcie ImageLine()s príslušnými parametrami. Ak by ste chceli vykresli vyplnený obdåžnik, musíte použifunkciu ImageFilledRectangle(). Táto funkcia má rov<strong>na</strong>ký poèet a špecifikáciu parametrovako funkcia ImageRectangle(). Rozdiel spoèíva v tom, že obdåžnik nepozostáva ibaz rámu, ale je vyplnený farbou, ktorú zadáte ako posledný parameter. To z<strong>na</strong>mená, žetakýto obdåžnik nebude ma žiadny vidite¾ný rám, pretože bude rov<strong>na</strong>kej farby akovýplò. Ak chcete vyplnený obdåžnik s rámom inej farby, musíte použi obe funkcieImageFilledRectangle() a ImageRectangle(), ako ukazuje <strong>na</strong>sledujúci príklad:Tento <strong>sk</strong>ript vykreslí obdåžnik s rámom farby definovanej v premennej $farba2 avýplòou farby definovanej v premennej $farba1. Najprv sa vykres¾uje obsah a až potomrám. Je to možné, prirodzene, spravi aj opaène, ale potom musí by výplò menšia, abynezakryla už <strong>na</strong>kreslený rám.GD knižnica takisto umožòuje kreslenie oblúkov, úplných i neúplných, vo všeobecnostielipsovitého tvaru. V tomto prípade nám prichádza <strong>na</strong> pomoc funkciaImageArc(), ktorá opä ako prvý parameter vyžaduje identifikátor obrázka, v ktoromchcete kresli . Ïalšie dva parametre charakterizujú stred elipsy (v prípade, ževykres¾ujete iba oblúk, charakterizujú súradnice stredu elipsy danej pre vykres¾ovanýoblúk), prièom <strong>na</strong>jprv zadávate x-ovú súradnicu a potom y-ovú. Ïalšie dva parametrešpecifikujú rozmery elipsy (resp. charakteristickej elipsy pre daný oblúk); <strong>na</strong>jprv musítezada šírku a následne jej výšku. Ïalšími dvoma parametrami urèíte, aká èas elipsy,resp. aký oblúk bude vykreslený. Prvý z týchto dvoch parametrov vyjadruje poèiatoènúa druhý koneènú pozíciu vykres¾ovaného oblúka v stupòoch, takže by tieto dvaparametre mali <strong>na</strong>dobúda hodnoty od 0 do 360. Poèiatoèná pozícia musí by menšiaako koncová. V prípade, že koncová pozícia prekroèí èíslo 360, je <strong>na</strong> òu použitá operáciamodulo 360 (teda za koncovú pozíciu sa považuje jej zvyšok po delení 360). Uholje urèený vzh¾adom <strong>na</strong> pomyselnú os x v obrázku, teda spomí<strong>na</strong>né parametre urèujúve¾kos uhla zovretého s osou x v smere hodinových ruèièiek. Ak teda chcete vykreslikruh, staèí zada rov<strong>na</strong>ké rozmery (šírka a výška), poèiatoènú pozíciu 0 a koncovú pozíciu360. Posledným parametrom funkcie je opä farba, ktorou má by oblúk vykreslený.Ak chcete kresli vyplnené elipsy/oblúky, musíte použi funkciu ImageFilledArc().Táto funkcia preberá všetky parametre od funkcie ImageArc() a pridáva ešte jeden –štýl. Tento posledný parameter zadáva funkcii spôsob, ktorým má by vyplnený oblúkvykreslený – ak zadáte 0, bude vykreslený klasický vyplnený oblúk (podobný odkrojenémuokrúhlemu koláèu, v prípade, že nezadáte vykreslenie úplnej elipsy) alebomôžete zada 1, èo vyjadruje „odseknutie“ oblúkovitej èasti kruhu, teda je vykreslenýtrojuholník. V poslednom prípade musí by rozdiel medzi koncovou a poèiatoènoupozíciou vykres¾ovaného oblúka menší ako 180, pretože i<strong>na</strong>k nie je možné trojuholníkvykresli a <strong>na</strong> obrázku sa neudejú žiadne zmeny. Väèšie využitie má však prvý uvedenýspôsob, ktorý sa dá využi <strong>na</strong>príklad <strong>na</strong> kreslenie koláèových grafov. Ukážka vykresleniaèiastky koláèového grafu:Predstavte si, že chcete urèitú ohranièenú èas obrázka vyma¾ova nejakou farbou.GD knižnica umožòuje takzvaný flood fill, èo by sa dalo interpretova ako vyliatie farby<strong>na</strong> jednom bode obrázka, prièom farba sa rozleje <strong>na</strong> všetky strany a pokraèuje, kýmne<strong>na</strong>razí <strong>na</strong> nejakú „bariéru“, ktorá v tomto prípade predstavuje nejakú inú farbu.Základnou floodovaciou funkciou je ImageFill(), ktorej použitie je ve¾mi jednoduché.Staèí jej zada identifikátor obrázka ako prvý parameter a x-ovú a y-ovú súradnicubodu, kde chcete zaèa s „rozlievaním“ farby, ako ïalšie dva parametre. Poslednýmparametrom je farba, ktorú chcete použi <strong>na</strong> floodovanie. Funkcia vyfarbí danou farbouzadaný bod (pixel) a všetky pri¾ahlé body rov<strong>na</strong>kej farby, akú mal pôvodne zadanýbod. Na floodovanie je možné miesto jednej farby použi aj vzorku, ktorá musí by predpoužitím definovaná funkciou ImageSetTile(). Jej použitie je podobné ako použitie užspomí<strong>na</strong>nej funkcie ImageSetBrush(). Najprv musíte vytvori obrázok (<strong>na</strong>pr. <strong>na</strong>èítanímzo súboru alebo pomocou funkcie ImageCreate()) a následne odovzda tento obrázokfunkcii ImageSetTile() ako druhý parameter. Prvým parametrom je opä obrázok, v ktoromchcete danú vzorku používa . Keï už vzorku nebudete potrebova , musíte opäuvo¾ni príslušnú pamä volaním ImageDestroy(). Po priradení vzorky danému obrázkustaèí miesto farby ako posledného parametra zada funkcii ImageFill() hodnotu $Tiled10/2001 PC REVUE 135