Spletni PHP krožek

8. teden

Ustvarjanje slik s PHPjem in knjižnico GD

V PHPju je že nekaj časa vključena knjižnica GD, s pomočjo katere lahko obdelujemo in ustvarjamo slike.

Primeri uporabe: števec obiskovalcev, grafi, predogledi (thumbnaili) slik v galeriji, dinamični avatarji in še kaj bi se našlo.

Začetek

Da bi lahko risali in/ali obdelovali sliko, jo moramo najprej ustvariti. Tukaj imamo dve možnosti:

Ustvarjanje nove (prazne) slike

Če kanimo sliko prikazati v formatu PNG ali JPEG, bomo uporabili funkcijo imagecreatetruecolor(x,y), s katero ustvarimo prazno sliko velikosti x × y pikslov. Primer ustvarjanja true color slike velikosti 640 × 480:

$slika = imagecreatetruecolor(640,480);

Podobno lahko storimo tudi, če želimo ustvariti 256-barvno GIF sliko:

$slika = imagecreate(640,480);

Ustvarjanje slike iz obstoječe datoteke

Druga možnost pa je, da ustvarimo sliko iz že obstoječe datoteke s sliko. Tu imamo glede na format slike več funkcij, vsaka pa sprejme en argument - pot/URL do slike:

za GIF: imagecreatefromgif()
za PNG: imagecreatefrompng()
za JPEG: imagecreatefromjpeg()

Za BMP ni vgrajene podpore - uporabiti boste morali funkciji, ki ju dobite tukaj.

Tip slike lahko dobimo s pomočjo funkcije mime_content_type() oz. ustrezne spremenljivke v polju naloženih datotek.

Primer, če imamo v isti mapi, kot je skripta, datoteko "slika.png":

$slika = imagecreatefrompng("slika.png");

Funkcije za manipuliranje slik

Funkciji imagesx(slika) in imagesy(slika) nam povesta širino in višino slike, z imagedestroy(slika) pa na koncu dela s sliko sprostimo njen prostor v pomnilniku.

Funkcija imagecopyresampled() nam omogoča, da sliko pomanjšamo / povečamo z minimalno izgubo kvalitete. Seveda lahko z njo skopiramo tudi samo en del slike.

Primer, kjer datoteko fotografija.jpg pomanjšamo na širino 150 pikslov in obdržimo razmerje stranic:

$original = imagecreatefromjpeg("fotografija.jpg");

$razmerje = imagesx($original) / imagesy($original);
$sirina = 150;
$visina = $sirina / $razmerje;

$kopija = imagecreatetruecolor($sirina,$visina);
imagecopyresampled($kopija,$original,0,0,0,0,$sirina,$visina,imagesx($original),imagesy($original));

imagedestroy($original);
imagedestroy($kopija);

Na koncu imamo v spremenljivki kopija shranjeno pomanjšano sliko.

Sliko lahko nato izrišemo na zaslon (v tem primeru PHP skripta ne sme brskalniku poslati nobenih drugih podatkov / besedila / HTML kode) ali pa jo shranimo v datoteko.

Ponovno je odvisno, v kakšnem formatu želimo datoteko izrisati/shraniti, na izbiro pa imamo naslednje funkcije:

za GIF: imagegif(slika[,datoteka])
za PNG: imagepng(slika[,datoteka])
za JPEG: imagejpeg(slika[,datoteka,kvaliteta 0-100])

Zgornjo pomanjšano sliko bi tako na zaslonu prikazali z dodatnima dvema vrsticama, ki ju vrinemo pred vrstico imagedestroy($kopija);.

header("Content-type: image/jpeg"); // obvezno
imagejpeg($kopija);

Če pa bi pomanjšano sliko želeli shraniti na disk pod imenom pomanjsana.jpg, bi to storili z ukazom

imagejpeg($kopija,"pomanjsana.jpg");

Funkcije za risanje po sliki

Ko imamo enkrat sliko (bodisi iz obstoječe datoteke ali prazno), lahko nanjo dodajamo geometrijske like in besedilo.

Pri dodajanju elementov na sliko moramo določiti tudi njihovo barvo, ki jo moramo pred tem ustvariti s funkcijo imagecolorallocate(slika,r,g,b), pri čemer so r, g in b vrednosti rdeče, zelene in modre komponente od 0 - 255. Ustrezne vrednosti teh treh parametrov za neko barvo lahko dobite v npr. Slikarju ali Photoshopu.

Primer:

$rdeca = imagecolorallocate($slika,255,0,0);

Dodajanje besedila na sliko

Na izbiro imamo dve funkciji - imagestring() (s katero na sliko dodamo besedilo v vgrajeni pisavi) in imagettftext() (s katero na sliko dodamo besedilo v pisavi iz poljubne TTF datoteke).

1. primer: na koordinati 5,5 (merjeno iz levega zgornjega kota slike) dodamo napis "Juhej naprej!" velikosti 3 v modri barvi:

$slika = imagecreatetruecolor(100,25);
$modra = imagecolorallocate($slika,0,0,255);
imagestring($slika,3,5,5,"Juhej naprej!",$modra);
header("Content-type: image/png");
imagepng($slika);
imagedestroy($slika);

2. primer: V pisavi Arial 12 bomo v rumeni barvi napisali "test" na koordinati 5,18:

$slika = imagecreatetruecolor(40,25);
$rumena = imagecolorallocate($slika,255,255,0);
imagettftext($slika,12.0,0,5,18,$rumena,"C:\\Program Files\\xampp\\htdocs\\arial.ttf","test");
header("Content-type: image/png");
imagepng($slika);
imagedestroy($slika);

Pot do TTF datoteke mora biti absolutna in ne relativna.

Risanje po sliki

Če ste zgornja primera preizkusili, ste opazili, da je ozadje slike črno - to lahko popravimo tako, da čez celotno sliko narišemo polnjen bel pravokotnik s funkcijo imagefilledrectangle():

$bela = imagecolorallocate($slika,255,255,255);
imagefilledrectangle($slika,0,0,imagesx($slika)-1,imagesy($slika)-1,$bela);

Koristne funkcije za risanje:

Črte: imageline()
Prazni pravokotniki: imagerectangle()
Polni pravokotniki: imagefilledrectangle()
Prazne elipse: imageellipse()
Polne elipse: imagefilledellipse()

Primer kode, ki nariše semafor:

<?php

$slika = imagecreatetruecolor(100,200);

$rdeca = imagecolorallocate($slika,255,0,0);
$rumena = imagecolorallocate($slika,255,255,0);
$zelena = imagecolorallocate($slika,0,255,0);
$crna = imagecolorallocate($slika,0,0,0);

$bela = imagecolorallocate($slika,255,255,255);
imagefilledrectangle($slika,0,0,imagesx($slika)-1,imagesy($slika)-1,$bela);

imagerectangle($slika,15,15,85,195,$crna);

imagefilledellipse($slika,50,50,50,50,$rdeca);
imagefilledellipse($slika,50,104,50,50,$rumena);
imagefilledellipse($slika,50,158,50,50,$zelena);

header("Content-type: image/png");
imagepng($slika);
imagedestroy($slika);

?>

Odgovori na pogosta vprašanja

V: Ali lahko ustvarim GIF animacije?

O: S privzetimi funkcijami ne, lahko pa si pomagate s temle.

V: Slika se mi na najetem strežniku ne prikaže, kaj je narobe?

O: Možno je, da vaš ponudnik spletnega gostovanja nima vključene podpore knjižnice GD. To lahko preprosto preverite tako, da na strežniku ustvarite datoteko test.php in vanjo napišete <? phpinfo(); ?> in jo odprete v brskalniku. Če je notri moč najti omenjeno besedo GD, podpora je, drugače pa jo ni. Če boste v svoji skripti poizkusili uporabiti funkcije knjižnice GD in le-ta ni nameščena na strežniku, boste dobili fatal error.

V: V FireFoxu namesto slike vidim samo zmazek besedila

O: Pozabili ste vrstico header() (katere rabo si lahko ogledate zgoraj).

V: Funkcija imagegif() na strežnik noče shraniti GIF datoteke - javi access denied

O: V nekaterih različicah PHPja je v tej funkciji hrošč - datoteko najprej ustvarite s funkcijo touch()

V: Odkar v svoji skripti uporabljam GD knjižnico, je strežnik občutno bolj obremenjen

O: Prepričajte se, da na koncu skritpe za vsako sliko kličete funkcijo imagedestroy(). Prav tako se lahko pri večjih slikah in velikem številu obiskovalcev hitro zgodi, da je strežnik preobremenjen. Pomagajte si tako, da sliko shranite v začasen direktorij in jo recimo ponovno ustvarite vsakih 15 minut - pomagajte si s funkcijo filectime()

V: Kje lahko dobim pisave za funkcijo imagettftext()?

O: Uporabniki Windowsov jih najdete v mapi c:\windows\fonts, veliko pisav lahko dobite tudi na spletni strani dafont.com

Zaključek

V tem kratkem vodiču po GD knjižnici seveda niso zajete vse funkcije, ki jih imate na razpolago - priporočam vam branje dokumentacije na php.net.