PHP kód képgaléria kezelésére

A PHP a GD2 csomag segítségével igen sok műveletre képes. Merem állítani, hogy bármely problémára, ami csak egy weboldalon a képkezeléssel kapcsolatban felmerülhet ott a megoldás. A képkezelési funkciókon végignézve nehéz elhinni, hogy még is vannak csúnya oldalak :)

Ma nincs igazán kiforrott modell a potál képanyagának kezelésére. Ezért is okozhat gondot sok helyen a kép alaú tartalommal való munka - pixeles miniatűrök, torz arányok, html-ben átméretezett képek (width, height). Igényes oldalakon is találkozunk ilyen problémákkal, és azt hiszem sokan másodrendű kérdésként kezelik. Tény, hogy sok munkába kerül, sőt kifejezetten nehézkes a képkezelést jól beépíteni az oldal rendszerébe.

A következő hasábokon egy lehetséges koncepciót szeretnék bemutatni. Próbáltam arra a szintre fejleszteni, hogy akár élesben is használható legyen. A cikk végén letölthető a teljes php kód egy minta implementációval (példák, beállított könyvtárak és .htaccess fájl). Örömmel várok minden hozzászólást.

Újrafelhasználható, beépíthető PHP képmanipuláló modul

Az elkészült kód reményeim szerint sok webszerkesztő életét megkönnyíti majd, akinek képekkel kell foglalkoznia. Az enyémet biztosan. Néhány a lehetőségek közül:

  • Tetszőleges keretek: lekerekíthető sarkok, akár csillag alakú képek
  • Design-elemek "befolyhatnak" a képre
  • Igazítható (align) vízjelek
  • Filter használható (imagefilter) pl fekete-fehér változat készítése
  • A verziók akkor generálódnak, ha szükség van rájuk:
    • feltöltéskor nem kell eldönteni, milyen szerepbe szánjuk a képet
    • fölösleges változatok nem keletkeznek
    • bármikor (pl. cron) törölhetjük a régen használt képeket (ha kell, visszajönnek)
  • CMS-független megoldás:
    • a jelenlegi CMSben egy betüt sem kell átírni
    • akár HTML alapú oldlak mellett is használható

A szkript mod_rewrite vagy ErrorDocument direktívával éppúgy használható.

Az elv

Egy feltöltött képből több verzió előállítható. Máshogy: a verziókat az köti össze, hogy ugynabból az eredeti (original) fájból származnak. A verziók elsősorban méretváltozatok, de nem csak azok lehetnek. Egy képnek lehet lekerekített, fekete-fehér, vagy modjuk vízjellel (a weboldal neve) ellátott változata is. A továbbiakban megpróbálok példát adni a leggyakrabban használt funkciók előcsalására a modul segítségével.

A gyakorlat

Legyen egy könyvtár, amiben a modul helyet foglal, már csak azért is, hogy olyan modulszerű legyen (mozgatható stb.), ezért itt a kep. (De akár gyökérkönytárba is telepíthetjük.) A handler.php, az egyetlen php szkript, felelős a verziók gyártásáért. Az eredeti képek az original könyvtárbn találhatók. Ez lehet akár csak egy symlink is. (Ha meglévő rendszerbe illeszted a modult, ez a lehetőség szimpatikus lesz).

A verziókat nevük azonosítja, úgy mint "kicsi" vagy "nagy", a példában: negyzet és csillag. Minden verzió-könyvtárban van egy .htconfig nevű file. Ez írja le miben is áll az aktuális változat. (Például méretek, de erről még később lesz szó részletesen).

kep | +- .htaccess | +- handler.php | +- original | +- 1.jpg | +- 2.jpg | +- negyzet | +- .htconfig | +- csillag +- .htconfig

Az egyszerűség kedvéért a feltöltött képeink legyenek 1.jpg és 2.jpg. Letöltődik az oldal, benne hivatkozással a kep/negyzet/1.jpg fájlra, és a böngésző lekéri azt:

Mivel a kért fájl nem létezik, a handler.php fut le (ehhez kell a RewriteRule vagy az ErrorDocument segítsége). Ő betölti a negyzet változathoz tartozó beállításokat, azaz a negyzet könyvtár .htconfig fájlját, ebben benne van, hogy egy 60x60 pixeles négyzetes képet szeretnénk. Betölti az original/1.jpg-t, majd átméretezi, elmenti, és el is küldi a kliensnek. Mivel a legyártott kép el is van mentve, a következő kérésnél már a webszerver szolgálja ki a fájlt, anélkül, hogy a php egyáltalán betöltődne.

(Bármikor le is törölhetjük az elmentett verziót, szükség esetén úgy is újragenerálódik. Így lehetőségünk van cache-ként kezelni a képek könyvtárát. A mai HDD árak mellett ez nem nagy megtakarítás, de ha sok elavult képünk van, hasznos lehet.)

Telepítés

Hozzuk létre a köynvtárakat. A verziók könyvtárainak írhatónak kell lenniük a webszerver (PHP) számára. A legtöbb szerveren ez más user, mint amivel az FTP működik, úgyhogy valószínűleg be kell kapcsolnod a "write by others" jogot. (Erről bővebb infót találsz bármilyen php segédanyagban, ami feltöltéssel foglalkozik).

A veziók nevei csak kisbetüket és számokat tartalmazhatnak, maximális hossz: 16 karakter.

Készíts egy .htaccess (igen, az első karakter egy pont) nevű file-t a kepek könyvtárban. Itt két lehetőséged van:

ErrorDocument 404 /kep/handler.php

Előny: gyors és a legtöbb webszerveren használható. Hátránya, hogy meg kell adnod a handler.php elérési útját a web főkönyvtárához képest. Ha később átnevezed vagy mozgatod a modult (nem valószínű, de ha mégis) ezt is meg kell változtatnod az új elérési útra.

Options +SymLinksIfOwnerMatch RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* handler.php [L]

Előny: a csomag helye nem számít. Hátrány: sok szerveren nincs engedélyezve.

Konfigurálás

Hozd létre a .htconfig fájlokat a verzióknak megfelelően. Ennek feladata a verzió tulajdonságainak megadása. A negyzet esetén mondjuk:

forcedw: 60 forcedh: 60

Lehet bonyolultabb is, például, ha a képet fekete-fehérré szeretnénk tenni, majd egy 130x100 méretű lyukas png segítségével csillag alakúra vágni:

forcedw: 130 forcedh: 100 over: overlay/csillag.png filter: IMG_FILTER_GRAYSCALE

Az előző példákban forced, azaz szigorú méretekkel dolgoztunk. Ebben a módban a szkript levágja a kép "fölösleges" részét. Nem mindig akarjuk a képeket ilyen szigorúan méretezni (sőt legtöbbször nem). A következő példa gyengén megadott méreteket tartalmaz (maxx, maxy). Ennek hatására egy (természetesen aránytartó) méretezés történik, hogy a kép beleférjen a megadott méretekbe, azaz egyik kiterjedése se legyen nagyobb a megadottnál. Vágás itt nincs.

Helyezzünk el vízjelet is a képen! Erre az előző példában is szereplő over paramétert hazsnáljuk. Itt egy relatív fájlnevet adtunk meg, de lehetne abszolút is (pl: $GLOBALS["_SERVER"]["DOCUMENT_ROOT"] . "/kep/overlay/vizjel.png"). Vízjelünket a jobb-alsó sarokba az attachment paraméterrel állíthatjuk. Az rb jelentése Right-Bottom, azaz jobb alsó sarok. (Alapértelmezett a bal felső). Használható karakterek: c - Center (vízszintesen középre); r - Right (jobbra); m - Middle (függőleges közép); b - Bottom (lent). (Sorrend, kis és nagybetű nem számít).

maxw: 1024 maxh: 1024 attachment: rb over: overlay/vizjel.png

PHP filter használata

Lehetőség van egy darab PHP filter használatára is. Ezt a filter paraméterrel állíthatjuk be. Itt lényegében az imagefilter függvény paramétereit kell megadnunk, az elsőt kivéve, mivel ezt a szkript menet közben generálja. Bővebben a PHP dokumentációban.

A fenti példában graysacle szűrő szerepelt. Lássunk egy paraméterekkel rendelkező szűrőt is először ahogy PHPben lenne:

imagefilter ($image, IMG_FILTER_COLORIZE, 255, 0, 255);

Ugyanehhez a gyönyörű rózsaszín hatáshoz a következőt kell beállítanunk az illetékes .htconfig fájlban:

filter: IMG_FILTER_COLORIZE, 255, 0, 255

Képméret beállítása

A forced és max közötti külsönbséget szemléltesse ez a két Nixon-fotó:

Kép méret beállítása
Kép méretezés módjai

Lehet olyan eset. amikor csak az egyik koordináta betartása a fontos, és abból semmiképen nem szeretnénk vágni. A kövekező példa a kép szélességét köti meg, de a magasságot csak maximálja. Készíthetünk modjuk filmszalag szerű futó képsort:

Kép méret beállítása
Csak egy méret fix

Fejre vigyázni

Ha álló képet kell vágni, nem elég matematikai középpontból kiindulni. Ha a kép álló, a vágott terület felül: 1/4, alul: 3/4 arányban oszlik meg. Ez elég egyszerű megoldás, de így lényegesen jobb hatású képek készíthetők. (Az arcok nem lesznek félbevágva).

Keretek

A legtöbb portállal nem foglalkozik külön grafikus, vagy grafikailag érzékeny szerkesztő. (Általában még arra is nehéz rávenni a tartalom szerkesztőit, hogy egy IrfanView vagy hasonló képnézegető programmal átszabják a képeket feltöltés előtt).

Gyakran előfordul, hogy, bekeretezett képeket töltenek fel, amik önmagukban jól nézek ki, de az ilyen képről készült miniatűrök mindenhonnan kiugranak az oldalon. Ha ilyen slendrián szerkesztőkkel van dolgod, hasznos lesz az (elég triviális) bordersafe paraméter. Lényegében egy 10%os zoom segítségével levágjuk a kép széleit (fotók esetén sem gond, a papírképről úgy is leesne). Ha volt ott keret, ha nem, ezután valószínűleg már nem lesz.

Keretek eltávolítása 10%os zoommal
10% zoommal a keretek ellen

Az opciót bekapcsolhatjuk, ha a bordersafe paraméternek nullától eltérő értéket adunk:

bordersafe: 1

Formára vágás

Különböző alakú képeket is készíthetünk az over paraméterrel. Csak el kell készítsük a formát kedvenc képszerkesztő programunkban és elmenteni PNG vagy akár GIF (nem szép) formátumban. Nem maszkot készítünk! Az elkészített kép egy keret lesz a weblap háttérszínével: ahol "lyukas" ott látszik majd az eredeti kép. De tovább is menetünk az egyszerű formázásnál. A következő példában egy kevésbé megszokott effektet adtunk a képhez:

Tetszőleges alakú képek késztése
Tetszőleges alak saját kerettel

Használhatnánk valódi maszkot, aminek alpha csatornája a képbe másolódik. Elegánsabb megoldás lenne, de mivel a jelenlegi IE nem támogatja a PNG áttetszőségét (csak megkerülő szkript megoldással), és a veszteséges JPG jobb méreteket ad a webre, a gyakorlat inkább ezt a módszert igazolja.

A fenti példa kódja:

forcedw: 100 forcedh: 100 over: overlay/fenykep.png

További paraméterek

Az elkészült képek mindig JPG formátumúak lesznek tekintet nélkül az eredeti fájlra. Alapértelmezésben a tömörítés minősége 75, ami a webre megfelelő. Jó minőséghez a 85 öt ajánlom, 95 fölött már nincs érzékelhető különbség. Ezt a quality paraméterrel állíthatjuk:

quality: 85

Lehetőségünk van az overhez hasonlóan a kép alatt is elhelyezni egy réteget. Például a háttérszínnel feltöltött üres képre helyezve egy átlátszó GIF vagy PNG is méretezhető (JPG végeredménnyel).

under: overlay/alap.jpg

Biztonság

Fájlfeltöltés

A legfontosabb: ne engedjünk .php kiterjesztésű fájlt feltölteni. Ezt kivédeni nem ezen rutin feladata, és ha fájlfeltöltést kezelő kód van a weblapon biztos megoldotta.

URL tiltás

Ha biztosra akrunk menni tiltsuk a php kiterjesztésű fájlok kiszolgálását. A következő sort (ha a mod_rewrite rendelkezésünkre áll) illesszük be a fent már említett .htaccess fájlunkba (az első két sor a rewrite funkció aktiválására szolgál, ha már benne van, ne ismételjük őket, elég az utolsó sor):

Options +SymLinksIfOwnerMatch RewriteEngine on RewriteRule .+/.+\.php - [NC,F]

Rejtett fájlok

Ha csodálkoztál, miért van ilyen furcsa, pontal kezdődő nevük a konfigurációs fájloknak, hát ezért. A *NIX világban ez jelzi a rejtett fájlokat. A webszerver picit szigrúbb ennél: az Apache alapbeállításon nem fogja megmutatni a ".ht" kezdetű fájlokat, így nem kell külön gondoskodnunk a konfigurációs fájlok védelméről a kíváncsi szemek ellen.

Megkötések

Tiltó szűrő működik a bellításokon, tehát csak az mehet át, ami engedélyezett. Ennek értelmében:

  • A verzók elnevezése (negyzet) csak kis betüket és számokat tartalmazhat, maximálisan 16 karakteren.
  • A képek nevében (kiterjesztéstől eltekintve) csak kis és nagybetü, számok, aláhúzás és kötőjelet (minusz) szerepelhet. Maximális hossz 64 karakter.
  • A kiterjesztés nincs ellenőrizve, de maximum 4 karakter lehet. Csak JPG, PNG és GIF formátumok töltődnek be.

Lásd még

  • Letöltés - A kód és egy teljes példa-implementáció letöltése (108K)
  • Ami innen kimaradt - Néhány fejlesztési megjegyzés, extra biztonsági paraméterek stb.