7. Dynamiczne generowanie grafiki

Transkrypt

7. Dynamiczne generowanie grafiki
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7. Dynamiczne generowanie grafiki
7.1. Biblioteka GD
Dynamiczne generowanie kodu HTML to podstawowe zastosowanie języka PHP. Często
jednak to nie wystarczy i mieszanka: dynamiczny HTML plus statyczna grafika, okazuje
się za słaba. Dlatego PHP można opcjonalnie wyposażyć w moduł umożliwiający
programowe tworzenie grafiki, a następnie wyemitowanie jej do przeglądarki w
powszechnie przyjętym formacie JPEG, PNG czy GIF. Moduł ten korzysta z biblioteki GD
(http://www.boutell.com/gd/). Standardowo PHP4 nie jest kompilowane z GD, musi to
zrobić sam administrator, dodatkowo GD może obsługiwać (lub nie) czcionki wektorowe
w formacie TrueType, za pośrednictwem biblioteki FreeType.
Grafikę w GD możemy generować bądź to zaczynając od pustego obrazka, bądź też
ładując jakąś gotową grafikę i dokonując na niej manipulacji. Repertuar biblioteki
obejmuje podstawowe funkcje graficzne (punkty, linie, wielokąty, elipsy), generację
tekstu (szczególnie ładnie wygląda wygładzany tekst generowany z wektorowych
czcionek TrueType), operacje na blokach obrazu, skalowanie, filtry i inne. Gotowy
obrazek można wysłać do przeglądarki, można też go przechować na dysku. Biblioteka
umożliwia tworzenie zarówno obrazków paletowych (mała ilość kolorów, ale też małe
rozmiary pliku), jak i obrazków w pełnym kolorze (24 bity RGB).
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.2. Sprawdzenie możliwości graficznych
Ze względu na opcjonalność samej biblioteki GD, jak i jej wielu komponentów, istnieje w
PHP funkcja gd_info() pozwalająca na zbadanie istnienia i możliwości GD w instalacji
PHP, na której wykonywany jest skrypt. Wynikiem działania tej bezparametrowej funkcji
jest tablica asocjacyjna prezentująca wersję i możliwości modułu dynamicznej generacji
grafiki.
'GD Version'
łańcuch tekstowy opisujący wersję biblioteki
'Freetype Support'
wartość logiczna – określa obsługę czcionek TrueType
'Freetype Linkage'
rodzaj biblioteki obsługującej czcionki TT (FreeType 1/2)
'T1Lib Support'
wartość logiczna – obsługa czcionek PostScript typ 1
'GIF Read Support'
wartość logiczna – odczyt obrazków GIF
'GIF Create Support' wartość logiczna – zapis obrazków GIF
'JPG Support'
wartość logiczna – zapis/odczyt obrazków JPEG
'PNG Support'
wartość logiczna – zapis/odczyt obrazków PNG
'WBMP Support'
wartość logiczna – zapis/odczyt obrazków WBMP
'XBM Support'
wartość logiczna – zapis/odczyt obrazków NetPBM
Z gd_info() warto korzystać pisząc kod przenośny między różnymi serwerami, w
przypadku braku którejś z funkcji można dzięki niej szybko zdiagnozować problem.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.3. Emitowanie grafiki
Skrypt PHP generujący obrazek różni się od skryptu generującego stronę w HTML. Przede
wszystkim nie jest to dokument HTML, zatem pozbawiony jest całkowicie nagłówka.
Dlatego kod generujący obrazek nigdy nie zaczyna się od <HTML>, to spowodowałoby
wygenerowanie nagłówka odpowiedzi HTTP z typem zawartości text/html co na pewno
nie jest dobrym typem MIME dla obrazka. Dlatego od razu, w pierwszej linii, startujemy
z kodem PHP. Niemniej jakiś nagłówek trzeba wygenerować, minimum to wymagane
pole Content-Type. Ze skryptu wysyłamy je w sposób następujący:
<?
header('Content-Type: image/png');
Oczywiście jeżeli docelowym formatem jest JPEG lub GIF, odpowiednio modyfikujemy
zawartość pola. Po załatwieniu sprawy nagłówka, rozpoczynamy pracę z grafiką od
stworzenia czystego bufora, bądź załadowania obrazka z pliku (o czym dalej). Następnie
dokonujemy na obrazku wszelakich manipulacji. W momencie, gdy jest gotowy,
wysyłamy go do przeglądarki funkcją imagepng(), imagejpeg(), czy też imagegif(). Ten
ostatni format nie jest generalnie zalecany. Dopiero jedna z tych funkcji powoduje
wysłanie danych obrazka do przeglądarki. Bardzo ważną sprawą jest wyłączenie
komunikatów o błędach we wszystkich funkcjach, które takie mogą zgłosić. W
przeciwnym wypadku komunikat wmiesza się w binarne dane obrazka, powodując jego
uszkodzenie. Komunikaty o błędach wyłączamy używając operatora @.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.4. Tworzenie czystego obrazka - imagecreate()
Jeżeli pracę z obrazem zaczynamy od zera, musimy najpierw stworzyć powierzchnię do
rysowania. Służą do tego dwie funkcje: imagecreate() tworzy bufor do pracy z paletą
kolorów, oraz imagecreatetruecolor(), tworząca bufor dla obrazka 24-bitowego:
$obraz = @imagecreate(szerokosc, wysokosc);
$obraz24 = @imagecreatetruecolor(szerokosc, wysokosc);
Obie funkcje zwracają wartość typu zasób, której używamy później jako identyfikatora
obrazu. Po zakończeniu rysowania obrazu, oraz wyemitowaniu go do przeglądarki,
można zniszczyć bufor roboczy funkcją imagedestroy(). Jeżeli tego nie zrobimy, bufor
zostanie zniszczony automatycznie przy wyjściu ze skryptu.
imagedestroy($obraz);
7.5. Ładowanie obrazka z pliku
Bardzo często umieszczamy naszą grafikę na jakimś gotowym tle. Najprościej w takim
wypadku stworzyć bufor do rysowania z załadowanego z dysku obrazka, przy pomocy
zestawu funkcji: createimagefromgif(), createimagefrompng(), createimagefromjpeg().
Parametrem tych funkcji jest ścieżka do pliku z obrazkiem, jeżeli włączone jest
traktowanie zasobów HTTP jako plików, to ścieżka może być adresem URL. Powstały
bufor z obrazkiem ma takie rozmiary jak oryginał, rodzaj (paleta/truecolor) również
zależy od obrazka.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.6. Więcej o emitowaniu obrazka
Funkcje emitujące obrazek posiadają możliwość przekierowania obrazka z przeglądarki
klienta do lokalnego pliku na serwerze. Oprócz tego imagejpeg() pozwala na regulację
jakości obrazka (siły kompresji) od 0 (najgorsza jakość) do 100 (najlepsza jakość).
Domyślną jakością obrazka JPEG jest 75. Oto przykłady:
imagepng($obrazek, '/home/user/public_html/obrazki/ob1.png');
imagejpeg($obrazek, 'ob2.jpg', 90);
Jeżeli chcemy podregulować jakość obrazka JPEG wysyłanego do przeglądarki, po prostu
pomijamy drugi parametr:
imagejpeg($obrazek, , 45);
Niektóre formaty (PNG przede wszystkim) pozwalają na progresywne wyświetlanie
obrazka. GD umożliwia na wykorzystanie tej cechy przy pomocy funkcji imageinterlace(),
którą możemy włączyć dla danego obrazka progresywność:
imageinterlace($obrazek, 1);
Oczywiście włączanie i wyłączanie progresywności w czasie rysowania nie ma znaczenia.
Liczy się stan tego ustawienia w momencie wykonywania emisji obrazka. Warto
pamiętać, że progresywność zwiększa czas emisji obrazka i jego rozmiar w bajtach.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.7. Rysowanie i kolory
Przed narysowaniem czegokolwiek jakimś kolorem, trzeba sobie ten kolor zarezerwować
(również przy obrazkach 24-bitowych, różnica jest taka, że na obrazku takim można
mieć praktycznie nieograniczoną ilość kolorów, na obrazku paletowym ilość kolorów
wynika z wielkości palety). Do przydziału kolorów służy funkcja imagecolorallocate():
$kolor = imagecolorallocate($obrazek, r, g, b);
Wynikiem jest numer koloru używany dalej przy rysowaniu. Na obrazkach paletowych
funkcja ta może zwrócić -1, jeżeli wykorzystamy wszystkie kolory z palety.
Zarezerwowane kolory można zwalniać funkcją imagecolordeallocate():
imagecolordeallocate($obrazek, $kolor);
Pozostawienie niezwolnionych kolorów nie niesie ze sobą żadnyck konsekwencji, zostaną
automatycznie zwolnione przy usuwaniu bufora.
Pierwsze wywołanie tej funkcji dla danego obrazka ustawia mu kolor tła, jeżeli obrazek
jest w trybie paletowym (obrazki 24-bitowe mają zawsze czarne tło).
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.8. Rysowanie: pojedyncze piksele
imagesetpixel($obrazek, x, y, $kolor);
(0, 0)
x
y
$kolor to numer koloru otrzymany z imagecolorallocate().
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.9. Rysowanie: linie
imageline($obrazek, x1, y1, x2, y2, $kolor);
(0, 0)
x1
y2
y1
$kolor to numer koloru otrzymany z imagecolorallocate().
x2
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.10. Rysowanie: prostokąty
imagerectangle($obrazek, x1, y1, x2, y2, $kolor);
(0, 0)
x1
y1
y2
$kolor to numer koloru otrzymany z imagecolorallocate().
x2
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.11. Rysowanie: wypełnione prostokąty
imagefilledrectangle($obrazek, x1, y1, x2, y2, $kolor);
(0, 0)
x1
y1
y2
$kolor to numer koloru otrzymany z imagecolorallocate().
x2
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.12. Rysowanie: elipsy
imageellipse($obrazek, x, y, w, h, $kolor);
(0, 0)
x
y
x2
h
w
$kolor to numer koloru otrzymany z imagecolorallocate().
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.13. Rysowanie: wypełnione elipsy
imagefilledellipse($obrazek, x, y, w, h, $kolor);
(0, 0)
x
y
x2
h
w
$kolor to numer koloru otrzymany z imagecolorallocate().
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.14. Rysowanie: wielokąty
$ile = 3;
$wierzcholki = array(x0, y0, x1, y1, x2, y2);
imagepolygon($obrazek, $wierzcholki, $ile, $kolor);
(0, 0)
x0, y0
x1, y1
x2, y2
$wierzcholki to tablica zawierająca jako kolejne elementy współrzędne x i y wierzchołków
Wielokąt jest automatycznie zamykany linią od ostatniego do pierwszego wierzchołka.
$kolor to numer koloru otrzymany z imagecolorallocate().
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.14. Rysowanie: wypełnione wielokąty
$ile = 3;
$wierzcholki = array(x0, y0, x1, y1, x2, y2);
imagefilledpolygon($obrazek, $wierzcholki, $ile, $kolor);
(0, 0)
x0, y0
x1, y1
x2, y2
$wierzcholki to tablica zawierająca jako kolejne elementy współrzędne x i y wierzchołków
Wielokąt jest automatycznie zamykany linią od ostatniego do pierwszego wierzchołka.
$kolor to numer koloru otrzymany z imagecolorallocate().
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.14. Rysowanie: fragmenty łuków
imagearc($obrazek, x, y, w, h, s, e, $kolor);
(0, 0)
x
x2
e
y
h
s
w
$kolor to numer koloru otrzymany z imagecolorallocate(). Kąty s i e są liczone w
stopniach, zawsze w kierunku ruchu wskazówek zegara.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 7: „Generowanie grafiki”.
7.15. Rysowanie: fragmenty elips
imagefilledarc($obrazek, x, y, w, h, s, e, $kolor);
(0, 0)
x
x2
e
y
h
s
w
$kolor to numer koloru otrzymany z imagecolorallocate(). Kąty s i e są liczone w
stopniach, zawsze w kierunku ruchu wskazówek zegara.