Dinamikus képek kezelése

Az ezen az órán vett függvények a GD nevû nyílt forráskódú programkönyvtáron
alapulnak.
A GD könyvtár olyan eszközcsoport, melynek segítségével futásidõben képeket
hozhatunk létre és kezelhetjük azokat. A GD-rõl a http://boutell.com/gd/
weboldal szolgál bõvebb információval. Ha a könyvtárat telepítettük és a PHP-t is
lefordítottuk, elkezdhetünk dinamikus képeket létrehozni a PHP grafikus függvé-
nyeivel. Sok rendszer még mindig a könyvtár egy régebbi változatát futtatja, amely
a képeket GIF formátumban hozza létre. A könyvtár késõbbi változatai licenszokok
miatt nem támogatják a GIF formátumot. Ha rendszerünkre a könyvtár egy újabb
változatát telepítettük, úgy is lefuttathatjuk a PHP-t, hogy a képalkotó függvények
kimeneti formátuma PNG legyen, amelyet a legtöbb böngészõ támogat.
A GD könyvtár segítségével menet közben hozhatunk létre bonyolult alakzatokat
a PHP grafikus függvényeivel. Az óra során a következõket tanuljuk meg:
• Hogyan hozzunk létre és jelenítsünk meg egy képet?
• Hogyan dolgozzunk a színekkel?
• Hogyan rajzoljunk alakzatokat, például köríveket, téglalapokat és sokszögeket?
• Hogyan töltsünk ki színnel alakzatokat?
• Hogyan kezeljük a TrueType betûtípusokat?
Képek létrehozása és megjelenítése
Mielõtt elkezdhetnénk a képekkel foglalkozni, elõször szert kell tennünk
egy képazonosítóra. Ezt az imagecreate() függvény segítségével tehetjük meg.
Ennek két paramétere van, az egyik a kép magasságára vonatkozik, a másik
a szélességére. Ekkor egy képazonosítót kapunk vissza, amelyet az órán tárgyalt
majdnem mindegyik függvény esetében használni fogunk.
Miután megkaptuk az azonosítót, már majdnem készen állunk arra, hogy megjelen
ítsük elsõ képünket a böngészõben. Ehhez az imagegif() függvényre van
szükségünk, amelynek paramétere a képazonosító. A 14.1. programban a kép létrehoz
ásához és megjelenítéséhez használt függvényeket láthatjuk.
14.1. program Dinamikusan létrehozott kép
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: imagegif($kep);
5: ?>
Fontos, hogy a Content-type fejlécsort minden egyéb elõtt küldtük a böngé-
szõnek. Közölnünk kell a böngészõvel, hogy egy képet küldünk, különben
a program kimenetét HTML-ként kezeli. A programot a böngészõ már közvetlenül
vagy egy IMG elem részeként hívhatja meg.
egy PHP készítette kép
A 14.1. ábrán láthatjuk a 14.1. program kimenetét.
Egy téglalapot hoztunk létre, de egyelõre nem tudjuk annak színét beállítani.
260 14. óra
A szín beállítása
A szín beállításához egy színazonosítóra van szükségünk. Ezt
az imagecolorallocate() függvénnyel kaphatjuk meg, amelynek paramétere
a képazonosító, illetve három 0 és 255 közötti egész szám, amelyek a vörös, zöld
és kék színösszetevõket jelentik. Egy színazonosítót kapunk vissza, amellyel ké-
sõbb alakzatok, kitöltések vagy szövegek színét határozhatjuk meg.
$piros = imagecolorallocate($kep, 255,0,0);
Az imagecolorallocate() függvény elsõ meghívásakor egyúttal átállítja
a paraméterül kapott alakzat színét is. Így ha az elõzõ kódrészletet hozzáadjuk
a 14.1. programhoz, egy vörös téglalapot kapunk.
Vonalak rajzolása
Mielõtt egy képre vonalat rajzolhatnánk, meg kell adnunk annak két végpontját.
A képet úgy képzeljük el, mint képernyõpontokból álló tömböt, melynek mindkét
tengelye 0-tól számozódik. A számozás kezdõpontja a kép bal felsõ sarka.
Más szóval az (5, 8) koordinátájú képpont a hatodik képpont fentrõl lefelé és
a kilencedik képpont balról jobbra számolva.
Dinamikus képek kezelése 261
14
14.1. ábra
Dinamikusan létrehozott
alakzat
Az imageline() függvény két képpont közé rajzol egy egyenest. A függvény
paraméterként egy képazonosítót vár, négy egész számot, amelyek az egyenes két
végpontjának koordinátáit jelentik, valamint egy színazonosítót.
Ha a 14.2. programban megrajzoljuk a téglalap egy átlóját.
14.2. program Egyenes rajzolása az imageline() függvénnyel
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: $piros = imagecolorallocate($kep, 255,0,0);
5: $kek = imagecolorallocate($kep, 0,0,255 );
6: imageline( $kep, 0, 0, 199, 199, $kek );
7: imagegif($kep);
8: ?>
Két színazonosítót kapunk, egyet a piros és egyet a kék színnek. Ezután a $kek
változóban tárolt azonosítót használjuk a vonal színének megadására. Fontos megjegyezn
ünk, hogy a vonal a (199, 199) és nem a (200, 200) koordinátákban végzõ-
dik, tekintve, hogy a képpontokat 0-tól kezdve számozzuk. A 14.2. ábrán
a 14.2. program eredményét láthatjuk.
262 14. óra
14.2. ábra
Egyenes rajzolása
az imageline()
függvénnyel
Alakzatok kitöltése
A PHP segítségével ugyanúgy kiszínezhetünk alakzatokat, mint kedvenc grafikai
programunkkal. Az imagefill() függvény bemenete egy képazonosító,
a kitöltés kezdõkoordinátái, valamint egy színazonosító. A függvény a kezdõ
képponttal megegyezõ színû szomszédos képpontokat a kijelölt színre állítja.
A 14.3. program a képet az imagefill() függvény meghívásával teszi egy kicsit
érdekesebbé.
14.3. program Az imagefill() függvény használata
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: $piros = imagecolorallocate($kep, 255,0,0);
5: $kek = imagecolorallocate($kep, 0,0,255 );
6: imageline( $kep, 0, 0, 199, 199, $kek );
7: imagefill( $kep, 0, 199, $kek );
8: imagegif($kep);
9: ?>
A 14.3. ábrán a 14.3. program kimenetét láthatjuk.
Dinamikus képek kezelése 263
14
14.3. ábra
Az imagefill() függv
ény használata
Körív rajzolása
Az imagearc() függvény segítségével köríveket rajzolhatunk. Bemenete
egy képazonosító, a középpont koordinátája, a szélességet meghatározó egész
szám, a magasságot meghatározó egész szám, egy kezdõ- és egy végpont
(fokban mérve), valamint egy színazonosító. A köríveket az óramutató járásának
megfelelõen, 3 órától kezdve rajzoljuk. A következõ kódrészlet egy negyed körívet
rajzol ki:
imagearc( $kep, 99, 99, 200, 200, 0, 90, $kek );
Ez egy olyan körívrészletet jelenít meg, melynek középpontja a (99, 99) koordiná-
tájú pontban van. A teljes magasság és szélesség 200-200 képpontnyi. A körív 3
óránál kezdõdik és 90 fokot rajzolunk (azaz 6 óráig).
A 14.4. program teljes kört rajzol és kék színnel tölti ki.
14.4. program Kör rajzolása az imagearc() függvénnyel
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: $piros = imagecolorallocate($kep, 255,0,0);
5: $kek = imagecolorallocate($kep, 0,0,255 );
6: imagearc( $kep, 99, 99, 180, 180, 0, 360, $kek );
7: imagefill( $kep, 99, 99, $kek );
8: imagegif($kep);
9: ?>
A 14.4. program kimenetét a 14.4. ábrán láthatjuk.
264 14. óra
Téglalap rajzolása
A PHP imagerectangle() függvényével téglalapot rajzolhatunk.
Az imagerectangle() bemenete egy képazonosító, a téglalap bal felsõ és jobb
alsó sarkának koordinátája, valamint egy színazonosító. A következõ kódrészlet
olyan téglalapot rajzol, melynek bal felsõ és jobb alsó koordinátái rendre (19, 19)
és (179, 179):
imagerectangle( $kep, 19, 19, 179, 179, $kek );
Az alakzatot ezután az imagefill() függvénnyel tölthetjük ki. Mivel ez meglehet
õsen gyakori mûvelet, a PHP-ban létezik az imagefilledrectangle()
függvény, amely ugyanazokat a bemeneti értékeket várja, mint
az imagerectangle(), de az általunk meghatározott színnel ki is tölti a téglalapot.
A 14.5. program egy kiszínezett téglalapot hoz létre és megjeleníti a böngé-
szõben.
Dinamikus képek kezelése 265
14
14.4. ábra
Kör rajzolása
az imagearc() függv
énnyel
14.5. program Téglalap rajzolása az imagefilledrectangle() függvénnyel
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: $piros = imagecolorallocate($kep, 255,0,0);
5: $kek = imagecolorallocate($kep, 0,0,255 );
6: imagefilledrectangle( $kep, 19, 19, 179, 179, $kek );
7: imagegif( $kep );
8: ?>
A 14.5. ábrán a 14.5. program által elõállított képet láthatjuk.
Sokszög rajzolása
Az imagepolygon() függvény segítségével kifinomultabb alakzatokat is rajzolhatunk.
E függvény bemenete egy képazonosító, a pontok koordinátáiból álló
tömb, az alakzat pontjainak számát jelzõ egész szám és egy színazonosító.
Az imagepolygon() bemenetét képezõ tömbnek számmal indexeltnek kell
lennie. Az elsõ két elem az elsõ pont koordinátáit adja meg, a második kettõ
a második pontét és így tovább. Az imagepolygon() függvény megrajzolja
a pontok közötti vonalakat és az utolsó pontot automatikusan összeköti
az elsõvel. Az imagefilledpolygon() függvény segítségével színnel kitöltött
sokszögek hozhatók létre.
266 14. óra
14.5. ábra
Téglalap rajzolása az
imagefilledrectangle()
függvénnyel
A 14.6. program egy kitöltött sokszöget rajzol és jelenít meg a böngészõben.
14.6. program Sokszög rajzolása az imagefilledpolygon() függvénnyel
1: 2: header("Content-type: image/gif");
3: $kep = imagecreate( 200, 200 );
4: $piros = imagecolorallocate($kep, 255,0,0);
5: $kek = imagecolorallocate($kep, 0,0,255 );
6: $pontok = array (10, 10,
7: 190, 190,
8: 190, 10,
9: 10, 190
10: );
11: imagefilledpolygon( $kep, $pontok, count
( $pontok )/2, $kek );
12: imagegif($kep);
13: ?>
Vegyük észre, hogy az összekötendõ pontok száma az imagefilledpolygon()
függvény hívásakor megegyezik a $pontok tömb elemei számának felével. A 14.6.
ábrán a 14.6. program eredményét láthatjuk.
Dinamikus képek kezelése 267
14
14.6. ábra
Sokszög rajzolása az
imagefilledpolygon()
függvénnyel
A színek átlátszóvá tétele
A PHP az imagecolortransparent() függvénnyel lehetõvé teszi, hogy
a kiválasztott színeket az ábrán belül áttetszõvé tegyük. A függvény bemenete
egy kép- és egy színazonosító. Ha a képet megjelenítjük egy böngészõben,
az imagecolortransparent() függvénynek átadott szín áttetszõ lesz.
A 14.7. program kimenete a sokszöget rajzoló programot úgy változtatja meg,
hogy az alakzat „úszni” fog a böngészõben, ahelyett, hogy egy háttérszín elõtt
jelenne meg.
14.7. program A színek átlátszóvá tétele
az imagecolortransparent() függvénnyel
1: 2: header("Content-type: image/gif");
3:
4: $kep = imagecreate( 200, 200 );
5: $piros = imagecolorallocate($kep, 255,0,0);
6: $kek = imagecolorallocate($kep, 0,0,255 );
7:
8: $pontok = array (10, 10,
9: 190, 190,
10: 190, 10,
11: 10, 190
12: );
13:
14: imagefilledpolygon( $kep, $pontok, count
( $pontok )/2, $kek );
15: imagecolortransparent( $kep, $piros );
16: imagegif($kep);
17: ?>
A 14.7. ábrán a 14.7. program kimenetét láthatjuk.
268 14. óra
Szövegek kezelése
Ha rendszerünkön vannak TrueType betûk, a képekre írhatunk is. A GD programk
önyvtár mellett szükségünk lesz a FreeType programkönyvtár telepítésére is. Ha
ezek rendelkezésünkre állnak, egy képben megjelenõ diagramokat és navigációs
elemeket is létrehozhatunk. A PHP biztosít számunkra egy olyan eszközt is, amellyel
ellenõrizhetjük, hogy a beírandó szöveg elfér-e a rendelkezésre álló helyen.
Szövegírás az imageTTFtext() függvénnyel
Az imageTTFtext() függvénnyel az ábrákra szöveget írhatunk. A függvény
nyolc bemenõ paramétere a következõ: képazonosító, méret, amely a kiírandó
szöveg magasságára utal, szög, a kezdõ x és y koordináták, színazonosító,
a TrueType betûtípus elérési útvonala és a kiírandó szöveg.
A kiírandó szöveg kezdõkoordinátája határozza meg, hol lesz a szöveg elsõ
karakterének alapvonala.
A 14.8. program egy karakterláncot ír az ábrára, majd az eredményt megjeleníti
a böngészõben.
Dinamikus képek kezelése 269
14
14.7. ábra
A színek átlátszóvá
tétele az imagecolortransparent()
függvénnyel
14.8. program Szövegírás az imageTTFtext() függvénnyel
1: 2: header("Content-type: image/gif");
3:
4: $kep = imagecreate( 400, 200 );
5: $piros = imagecolorallocate($kep, 255,0,0);
6: $kek = imagecolorallocate($kep, 0,0,255 );
7: $betukeszlet = "/usr/local/office52/share/fonts/
/TrueType/arial.ttf";
8:
9: imageTTFtext( $kep, 50, 0, 20, 100, $kek,
$betukeszlet, "Üdvözöljük!" );
10:
11: imagegif($kep);
12: ?>
Létrehozunk egy 400 képpontnyi széles és 200 képpontnyi magas vásznat, megadunk
két színt és a $betukeszlet változóban tároljuk a TrueType betûtípus el-
érési útját. Ezután ráírjuk az ábrára a “Üdvözöljük!” szöveget. Figyelem, a betûtí-
pusok a kiszolgálón feltehetõleg más könyvtárban találhatók! Ha nem vagyunk
biztosak a helyben, keressük a .ttf kiterjesztésû fájlokat.
Az imageTTFtext() meghívásához az 50-es magasságot, 0 fokos szöget és
(20, 100) kezdõkoordinátát adtuk át. Emellett a függvény megkapja még a $kek
változóban tárolt színazonosítót és a $betukeszlet változóban tárolt betûtípust,
végül a kiírandó szöveget. Az eredményt a 14.8. ábrán láthatjuk.
270 14. óra
14.8. ábra
Szöveg írása az
imageTTFtext() függv
énnyel
Persze most még csak találgatunk, hová tegyük a szöveget. A betûméret nem árul
el sokat a szöveg magasságáról, a szélességérõl még kevesebbet.
Az imageTTFtext() függvény persze visszaad információt a szöveg kiterjedésé-
rõl, de akkorra már minden eldõlt. Szerencsére a PHP lehetõséget nyújt arra, hogy
próbálkozzunk, mielõtt még élesben elvégeznénk a mûveletet.
Szöveg kiterjedésének ellenõrzése
az imageTTFbox() függvénnyel
A szöveg kiterjedésérõl az imageTTFbox() függvénnyel szerezhetünk informá-
ciót, amely onnan kapta nevét, hogy a szöveget határoló dobozt írja le. A függvény
bemenete a betûméret, a szög, a betûtípus elérési útja és a kérdéses szöveg.
Azon kevés függvények egyike, melyekhez nem kell a képazonosító. Egy nyolcelem
û tömböt ad vissza, amely a szöveg kiírásához szükséges terület paramétereit
(koordinátáit) tartalmazza. A 14.1. táblázatban a függvény által visszaadott tömböt
értelmezzük.
14.1. táblázat Az imageTTFbox() függvény által visszaadott tömb
Sorszám Leírás
0 bal alsó (vízszintes tengely)
1 bal alsó (függõleges tengely)
2 jobb alsó (vízszintes tengely)
3 jobb alsó (függõleges tengely)
4 jobb felsõ (vízszintes tengely)
5 jobb felsõ (függõleges tengely)
6 bal felsõ (vízszintes tengely)
7 bal felsõ (függõleges tengely)
A függõleges tengelyhez visszaadott számok (1-es, 3-as, 5-ös, és 7-es tömbelemek)
a szöveg alapvonalához viszonyulnak, amelynek koordinátája 0. A szöveg tetejének
a függõleges tengelyen mért értékei ehhez képest általában negatív számok, míg
a szöveg aljának itt mért értékei általában pozitívak. Így kapjuk meg, hány
képponttal nyúlik a szöveg az alapvonal alá. Az imageTTFbox() által figyelembe
vett koordinátarendszert úgy kell elképzelnünk, mintha a szöveg alapvonala lenne
az y irányban vett 0 érték és a negatív koordináták attól felfelé, a pozitívak pedig
attól lefelé helyezkednének el. Így például ha az imageTTFbox() függvénnyel
ellenõrizendõ szövegben van egy "y", a visszakapott tömbben az 1-es indexû
elem lehet, hogy 3 lesz, mivel az "y" alsó szára három képponttal nyúlik
Dinamikus képek kezelése 271
14
az alapvonal alá. Lehetséges, hogy a 7-es elem –10 lesz, mivel a szöveg 10 képponttal
van az alapvonal fölé emelve. A pontos értékek betûtípustól és betûmérett
õl függnek.
Csak hogy bonyolítsuk a helyzetet, úgy tûnik, hogy az imageTTFbox() függvény
által visszaadott alapvonal és a rajzolás közben látható között 2 képpontos eltolás
van. Ezt úgy ellensúlyozhatjuk, hogy az alapvonalat két képpontnyival magasabbnak
képzeljük, mint amilyennek az imageTTFbox() függvény mutatja.
A vízszintes tengelyen a bal oldali számok (a 0-ás és a 6-os elem) esetében
az imageTTFbox() függvény az adott kezdõpont elõtt kezdõdõ szöveget negatív
számmal kifejezett eltolással jelöli. Ez általában alacsony szám, mivel a betûk jellemz
õen jelentõsebb eltérést mutatnak az alapvonaltól, mint az x irányú kezdõkoordiná-
tától (gondoljunk a p, g vagy j betûkre). A vízszintes tengelyen így már csak
az elvárt pontosság kérdése, hogy szükségünk van-e a koordináták kiigazítására.
Az imageTTFbox() függvény által visszaadott értékeket arra is használhatjuk,
hogy az ábrán belül a szöveget igazítsuk. A 14.9. program dinamikusan küldi
a böngészõnek a szöveget, úgy, hogy mind a vízszintes, mind a függõleges
tengelyen középre helyezi azt.
14.9. program Szöveg elhelyezése az imageTTFbox() függvény használatával
1: 2: header("Content-type: image/gif");
3: $magassag = 100;
4: $szelesseg = 200;
5: $betumeret = 50;
6: if ( ! isset ( $szoveg ) )
7: $szoveg = "Változtasson meg!";
8: $kep = imagecreate( $szelesseg, $magassag );
9: $piros = imagecolorallocate($kep, 255,0,0);
10: $kek = imagecolorallocate($kep, 0,0,255 );
11: $betukeszlet = "/usr/local/office52/share/fonts/
/TrueType/arial.ttf";
12: $szovegszelesseg = $szelesseg;
13: $szovegmagassag;
14: while ( 1 )
15: {
16: $doboz = imageTTFbox( $betumeret, 0,
$betukeszlet, $szoveg );
17: $szovegszelesseg = abs( $doboz[2] );
18: $szovegmagassag = ( abs($doboz[7]) )-2;
272 14. óra
14.9. program (folytatás)
19: if ( $szovegszelesseg < $szelesseg - 20 )
20: break;
21: $betumeret--;
22: }
23: $gifXkozep = (int) ( $szelesseg/2 );
24: $gifYkozep = (int) ( $magassag/2 );
25: imageTTFtext( $kep, $betumeret, 0,
26: (int) ($gifXkozep-($szovegszelesseg/2)),
27: (int) ($gifYkozep+($szovegmagassag/2)),
28: $kek, $betukeszlet, $szoveg );
29: imagegif($kep);
30: ?>
A kép magasságát és szélességét a $magassag és $szelesseg változókban
tároljuk, a betûtípus alapbeállítású méretét pedig 50-re állítjuk. Megvizsgáljuk,
hogy létezik-e már a $szoveg nevû változó; ha nem, beállítjuk egy alapértékre.
Ezzel az eljárással egy ábrának is lehetnek paraméterei, fogadhat adatot
egy weboldalról – akár egy URL keresõkifejezésébõl, akár egy kitöltött ûrlapról.
A képazonosító elõállításához az imagecreate() függvényt használjuk. A színazonos
ítókat a szokásos módon állítjuk elõ, a $betukeszlet nevû változóban
pedig a TrueType betûtípus elérési útját rögzítjük.
Azt szeretnénk, hogy a $szoveg változóban tárolt karaktersorozat elférjen
a rendelkezésére álló helyen, de egyelõre nem tudhatjuk, hogy ez sikerülni fog-e.
A while utasításon belül átadjuk a betûtípus elérési útját és a szöveget
az imageTTFbox() függvénynek, az eredményül kapott tömböt pedig a $doboz
változóba helyezzük. A $doboz[2] tartalmazza a jobb alsó sarok helyét
a vízszintes tengelyen. Ezt vesszük a karaktersorozat szélességének és
a $szovegszelesseg változóban tároljuk.
A szöveget függõlegesen is középre szeretnénk helyezni, de a szöveg alapvonala
alatt lévõ részt figyelmen kívül hagyva. Az alapvonal feletti magasság meghatároz
ásához használhatjuk a $doboz[7] változóban található szám abszolút értékét,
bár ezt még ki kell igazítanunk a fent említett két képponttal. Ezt az értéket
a $szovegmagassag változóban tároljuk.
Most, hogy kiszámítottuk a szöveg szélességének értékét, összevethetjük az ábra
szélességével (tíz képpontnyival kell kevesebbnek lennie, a keret miatt). Ha a szö-
veg keskenyebb, mint a kép szélessége, befejezzük a ciklust. Ellenkezõ esetben
csökkentjük a betûméretet és újra próbálkozunk.
Dinamikus képek kezelése 273
14
A $magassag és a $szelesseg változók értékét elfelezve megkapjuk az ábra
hozzávetõleges középpontját. A szöveget az ábra középpontjából és a szöveg
magasságából, illetve szélességébõl kiszámított eltolással az ábrára írjuk, végül
megjelenítjük a képet a böngészõben. A 14.9. ábrán láthatjuk a 14.9. program kimenet
ét.
Ezt a kódot egy másik oldal is meghívhatja, egy IMG elem részeként. A következõ
részlet egy olyan programot hoz létre, amely lehetõvé teszi az egyes felhasználóknak,
hogy saját szöveget jelenítsenek meg az ábrán:
1: 2: if ( ! isset( $szoveg ) )
3: $szoveg = "Dinamikus szöveg!";
4: ?>
5:


6:
7:

8:


9:
Amikor a 14.9. programot meghívjuk, egy olyan keresõkifejezéssel egészítjük ki
a hívást, amely tartalmazza a megjelenítendõ szöveget. A tizenkilencedik órában
többet is tanulhatunk az információk programról programra való átadásáról.
274 14. óra
14.9. ábra
Szöveg elhelyezése az
imageTTFbox() függv
ény használatával
A fenti elemek összegyúrása
Készítsünk egy példát az ezen az órán tanult függvények használatával! Tegyük
fel, hogy arra kértek bennünket, hogy készítsünk egy dinamikus oszlopgrafikont,
amely több címkézett számot hasonlít össze. Az egyes oszlopok alatt a megfelelõ
címkének kell lennie. Ügyfelünknek tudnia kell módosítani a grafikon oszlopainak
számát, a kép szélességét és magasságát és a grafikont körülvevõ keret méretét.
A grafikont fogyasztói szavazáshoz fogják használni, így az adatokat csak látszólagos
pontossággal kell megjeleníteni. Egy sokkal részletesebb lebontást az ábrát
tartalmazó oldal HTML részében találhatunk.
Az oszlopokat és értékeiket a legegyszerûbb módon egy asszociatív tömbben
tárolhatjuk. Miután megvan ez a tömb, ki kell számolnunk az oszlopok számát és
a tömb legnagyobb értékét:
$cellak = array ( "tetszik"=>200, "nem tetszik"=>400,
"közömbös"=>900 );
$max = max( $cellak );
$cellaszam = count( $cellak );
Létre kell hoznunk néhány változót, így ügyfelünk egyéni igényeihez igazíthatja
az ábrát:
$teljesszelesseg = 400;
$teljesmagassag = 200;
$xmargo = 20; // jobb és bal margó
$ymargo = 20; // felsõ és alsó margó
$oszlopkoz = 5; // az oszlopok közötti hely
$alsokeret = 40; // az ábra alján kimaradó hely
å (a margót nem számolva)
$betukeszlet = "/usr/local/office52/share/fonts/
å /TrueType/arial.ttf";
Ügyfelünk a változók módosításával meghatározhatja az ábra magasságát és széless
égét. Az $xmargo és $ymargo a grafikon körüli margóvastagságot adja meg.
Az $oszlopkoz az oszlopok közötti távolságot határozza meg, az $alsokeret
változó pedig az oszlopok alatti címkéknek szánt hely nagyságát.
Most hogy megvannak ezek az értékek, a némi számolgatás árán belõlük kapott
hasznos számokat változókba tesszük:
Dinamikus képek kezelése 275
14
$vaszonszelesseg = ( $teljesszelesseg - $xmargo*2 );
$vaszonmagassag = ( $teljesmagassag - $ymargo*2 - $alsokeret
);
$xPoz = $xmargo; // a rajzolás kiindulópontja az x tengelyen
$yPoz = $teljesmagassag - $ymargo - $alsokeret; //
å a rajzolás kiindulópontja az y tengelyen
$cellaszelesseg = (int) (( $vaszonszelesseg - ( $oszlopkoz *
å ( $cellaszam-1 ) )) / $cellaszam) ;
$szovegmeret = (int)($alsokeret);
Kiszámítjuk a rajzfelületet (azt a területet, ahová majd az oszlopok kerülnek).
A vízszintes összetevõt úgy kapjuk meg, hogy a teljes szélességbõl kivonjuk
a margó kétszeresét. A függõleges mérethez az $alsokeret változót is számításba
kell vennünk, hogy a címkéknek helyet hagyjunk. Az $xPoz tárolja azt az x
koordinátát, amelytõl az oszlopok rajzolását kezdjük, így ennek értékét
az $xmargo változó értékére állítjuk, amely a margó értékének vízszintes összetev
õjét tárolja. Az oszlopok talppontját tároló $yPoz változó értékét úgy
kapjuk meg, ha az ábra teljes magasságából kivonjuk a margót és a címkéknek
kihagyott hely nagyságát, amelyet az $alsokeret változóban tároltunk.
A $cellaszelesseg az egyes oszlopok szélességét tárolja. Ahhoz, hogy
az értékét megkapjuk, számoljuk ki az oszlopok közötti helyek összegét,
ezt vonjuk ki a diagram szélességébõl, majd az eredményt osszuk el az oszlopok
számával.
Kezdetben úgy állítjuk be a szöveg méretét, hogy egyezzen a szöveg számára
szabadon maradt terület magasságával (amit az $alsokeret változóban tárolunk).
Mielõtt megkezdenénk a munkát az ábrával, meg kell határoznunk a szöveg
méretét. Viszont nem tudjuk, milyen szélesek lesznek a címkék és mindenképpen
azt szeretnénk, hogy az egyes címkék elférjenek a felettük levõ oszlop szélessé-
gén belül. A $cellak tömbön egy ciklus segítségével meghatározzuk
a legnagyobb címke méretét:
forach( $cellak as $kulcs => $ertek )
{
while ( 1 )
{
$doboz = ImageTTFbBox( $szovegmeret, 0,
$betukeszlet, $kulcs );
$szovegszelesseg = $doboz[2];
if ( $szovegszelesseg < $cellaszelesseg )
break;
$szovegmeret—;
}
}
276 14. óra
Minden elem esetében egy ciklust kezdve, az imageTTFbox() segítségével
információt szerzünk a címke méretét illetõen. A kapott értéket a $doboz[2]
változóban találhatjuk meg, amit összevetünk a $cellaszelesseg változóval,
amely egy oszlop szélességét tartalmazza. A ciklust abban az esetben állítjuk le,
ha a szöveg szélessége kisebb, mint az oszlopszélesség. Egyébként pedig
csökkentjük a $szovegmeret értékét és újra ellenõrizzük a méreteket.
A $szovegmeret addig csökken, míg a tömb összes címkéje kisebb nem lesz
az oszlopszélességnél.
Most már végre létrehozhatunk egy képazonosítót és elkezdhetünk dolgozni vele.
$kep = imagecreate( $teljesszelesseg, $teljesmagassag );
$piros = ImageColorAllocate($kep, 255, 0, 0);
$kek = ImageColorAllocate($kep, 0, 0, 255 );
$fekete = ImageColorAllocate($kep, 0, 0, 0 );
forach( $cellak as $kulcs => $ertek )
{
$cellamagassag = (int) (($ertek/$max) * $vaszonmagassag);
$kozeppont = (int)($xPoz+($cellaszelesseg/2));
imagefilledrectangle( $kep, $xPoz, ($yPoz-$cellamagassag),
($xPoz+$cellaszelesseg), $yPoz, $kek );
$doboz = ImageTTFBox( $szovegmeret, 0, $betukeszlet,
$kulcs );
$szovszel = $doboz[2];
ImageTTFText( $kep, $szovegmeret, 0, ($kozeppont-
($szovszel/2)),
($teljesmagassag-$ymargo), $fekete, $betukeszlet,
$kulcs );
$xPoz += ( $cellaszelesseg + $oszlopkoz);
}
imagegif( $kep );
Ezt az imagecreate() függvénnyel tesszük meg, majd kiosztunk néhány színt is.
Újra végiglépkedünk a $cellak tömbön. Kiszámítjuk az oszlop magasságát és
az eredményt a $cellamagassag-ba helyezzük. Kiszámoljuk a középpont x koordin
átáját, amely megegyezik az $xPoz és a fél oszlop szélességének összegével.
Az imagefilledrectangle() függvénynek az $xPoz, $yPoz,
$cellamagassag és $cellaszelesseg változókat átadva megrajzoljuk
az oszlopot.
Dinamikus képek kezelése 277
14
A szöveg középre igazításához megint szükségünk van az imageTTFbox()
függvényre, amelynek eredménytömbjét a $doboz változóban tároljuk.
A $doboz[2] értéket fogjuk munkaszélességnek választani, ezt bemásoljuk
a $szovszel átmeneti változóba. Most már elegendõ információ áll rendelkezé-
sünkre ahhoz, hogy kiírassuk a címkét. Az x koordináta a $kozeppont változó és
a szövegszélesség felének különbsége lesz, az y koordináta pedig az alakzat
magasságának és a margónak a különbsége.
Megnöveljük az $xPoz változót, felkészülve ezzel a következõ oszlop feldolgoz
ására.
A ciklus végeztével megjelenítjük az elkészült képet.
A teljes programot a 14.10. példában láthatjuk, a végeredményt pedig
a 14.10. ábrán.
14.10. program Egy dinamikus oszlopdiagram
1: 2: header("Content-type: image/gif");
3: $cellak = array ( "tetszik"=>200,
"nem tetszik"=>400,
"közömbös"=>900 );
4: $max = max( $cellak );
5: $cellaszam = count( $cellak );
6: $teljesszelesseg = 300;
7: $teljesmagassag = 200;
8: $xmargo = 20; // jobb és bal margó
9: $ymargo = 20; // fenti és lenti margó
10: $oszlopkoz = 10; // az oszlopok közötti hely
11: $alsokeret = 30; // az ábra alján kimaradó hely
(a margót nem számolva)
12: $betukeszlet = "/usr/local/office52/share/fonts/
/TrueType/arial.ttf";
13: $vaszonszelesseg = ( $teljesszelesseg - $xmargo*2 );
14: $vaszonmagassag = ( $teljesmagassag - $ymargo*2
- $alsokeret );
15: $xPoz = $xmargo; // a rajzolás kiindulópontja
az x tengelyen
16: $yPoz = $teljesmagassag - $ymargo - $alsokeret; //
a rajzolás kiindulópontja az y tengelyen
17: $cellaszelesseg = (int) (( $vaszonszelesseg -
( $oszlopkoz * ( $cellaszam-1 ) )) / $cellaszam) ;
278 14. óra
14.10. program (folytatás)
18: $szovegmeret = (int)($alsokeret);
19: // betûméret kiigazítása
20: forach( $cellak as $kulcs => $ertek )
21: {
22: while ( 1 )
23: {
24: $doboz = ImageTTFbBox( $szovegmeret, 0,
$betukeszlet, $kulcs );
25: $szovegszelesseg = abs( $doboz[2] );
26: if ( $szovegszelesseg < $cellaszelesseg )
27: break;
28: $szovegmeret—;
29: }
30: }
31: $kep = imagecreate( $teljesszelesseg,
$teljesmagassag );
32: $piros = ImageColorAllocate($kep, 255, 0, 0);
33: $kek = ImageColorAllocate($kep, 0, 0, 255 );
34: $fekete = ImageColorAllocate($kep, 0, 0, 0 );
35: $szurke = ImageColorAllocate($kep, 100, 100, 100 );
36:
37: forach( $cellak as $kulcs => $ertek )
38: {
39: $cellamagassag = (int) (($ertek/$max) *
$vaszonmagassag);
40: $kozeppont = (int)($xPoz+($cellaszelesseg/2));
41: imagefilledrectangle( $kep, $xPoz,
($yPoz-$cellamagassag),
($xPoz+$cellaszelesseg),
$yPoz, $kek );
42: $doboz = ImageTTFbBox( $szovegmeret, 0,
$betukeszlet, $kulcs );
43: $szovszel = $doboz[2];
44: ImageTTFText( $kep, $szovegmeret, 0,
($kozeppont-($szovszel/2)),
45: ($teljesmagassag-$ymargo), $fekete,
$betukeszlet, $kulcs );
46: $xPoz += ( $cellaszelesseg + $oszlopkoz);
47: }
48: imagegif( $kep );
49: ?>
Dinamikus képek kezelése 279
14
Összefoglalás
A GD programkönyvtár PHP-s támogatása lehetõvé teszi, hogy dinamikus oszlopdiagramokat
és navigációs elemeket hozhassunk létre, viszonylag könnyen.
Ezen az órán megtanultuk, hogyan használjuk az imagecreate() és
az imagegif() függvényeket képek létrehozására és megjelenítésére.
Azt is megtanultuk, hogyan szerezzünk színazonosítót és hogyan töltsünk ki
színnel területeket az imagecolorallocate() és az imagefill() függvé-
nyekkel. Megnéztük, hogyan használjunk vonal- és alakzat függvényeket alakzatok
körvonalainak megrajzolására és kitöltésére. Megtanultuk, hogyan használjuk
a PHP által támogatott FreeType programkönyvtárat a TrueType betûtípusokkal
való munkára, valamint elemeztünk egy programot, amelyben egy alakzatra
szöveget írtunk és megnéztünk egy példát, amelyben a tanult eljárásokat
a gyakorlatban is láthattuk.
Kérdések és válaszok
Fellépnek-e teljesítménybeli problémák dinamikus képek használata
esetén?
Egy dinamikusan létrehozott kép lassabban töltõdik be a böngészõbe, mint egy
már létezõ fájl. A program hatékonyságától függõen ezt a felhasználó nem feltétlen
ül veszi észre, de azért a dinamikus képeket módjával használjuk.
280 14. óra
14.10. ábra
Egy dinamikus oszlopdiagram
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Milyen fejlécsort kell a böngészõnek küldenünk a GIF kép létrehozása és
megjelenítése elõtt?
2. Milyen függvényt használnánk egy képazonosító elõállításához, amelyet
a többi függvénynél használhatunk?
3. Milyen függvényt használnánk a létrehozott GIF kép megjelenítésére?
4. Milyen függvény segítségével szerezhetjük meg a színazonosítót?
5. Melyik függvénnyel rajzolnánk vonalat egy dinamikus képre?
6. Melyik függvénnyel töltenénk ki színnel egy dinamikus alakzatot?
7. Melyik függvényt használhatjuk körív rajzolására?
8. Hogyan rajzoljunk téglalapot?
9. Hogyan rajzoljunk sokszöget?
10. Melyik függvénnyel írnánk egy dinamikus alakzatra (a FreeType programk
önyvtár segítségével)?
Feladatok
1. Írjunk egy programot, amely egy folyamatjelzõt hoz létre, amely mutatja,
mennyi pénz folyt be egy gyûjtés alkalmával az adott célra szükséges pénzbõl.
2. Írjunk egy programot, amely egy fõcímet ábrázoló képet ír ki egy bejövõ ûrlap
vagy lekérdezés adataiból. Tegyük lehetõvé, hogy a felhasználó határozza
meg a rajzterületet, az elõtér és a háttér színét, valamint az árnyék meglét-
ét és annak méretét.