8. Dynamiczne generowanie grafiki, cz. 2 8.1. Generowanie tekstu

Transkrypt

8. Dynamiczne generowanie grafiki, cz. 2 8.1. Generowanie tekstu
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
8. Dynamiczne generowanie grafiki, cz. 2
8.1. Generowanie tekstu
Chociaż tekst można umieścić na grafice korzystając z HTML (używając grafiki jako tła
obiektu), często wygodniej jest umieścić tekst bezpośrednio w obrazku. W tym celu do
dyspozycji mamy funkcje tekstowe w module GD. Tekst może zostać wypisany
czcionkami bitmapowymi (wbudowane, lub załadowane z pliku w specyficznym
formacie), postscriptowymi, lub TrueType, najczęściej wykorzystuje się te ostatnie ze
względu na wysoką jakość tekstu (wygładzanie, hinting, polskie znaki).
8.2 Tekst bitmapowy
O tym rodzaju tekstu wspominam jedynie dla porządku. Czcionka jest zdefiniowana jako
jednokolorowa bitmapa, do dyspozycji jest 6 czcionek wbudowanych o różnych
wielkościach, można też załadować czcionkę z pliku (imageloadfont()). Jest to jednak
czcionka w formacie specyficznym dla GD, edycji trzeba dokonywać ręcznie, co jest
bardzo niewygodne (w dodatku przy zapisie trzeba zwrócić uwagę na kolejność bajtów w
słowie, format tego nie definiuje!). Na domiar złego czcionki bitmapowe muszą mieć
stałą szerokość znaku. Dopuszczalne kierunki tekstu to poziomy (funkcja imagestring()),
lub pionowy w górę (funkcja imagestringup()). Funkcji tych używamy w następujący
sposób:
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
imagestring($obrazek, $czcionka, $x, $y, $tekst, $kolor);
gdzie:
● $obrazek – identyfikator obrazka,
● $czcionka – numer czcionki, od 0 do 5 włącznie to czcionki wbudowane, wyższe
numery zwraca nam imageloadfont(),
● $x, $y – współrzędne punktu początkowego napisu (na linii bazowej tekstu),
● $tekst – łańcuch tekstowy do wydrukowania,
● $kolor – kolor zarezerwowany wcześniej przez imagecolorallocate().
8.3. Tekst z czcionek wektorowych w formacie TrueType
Znacznie wygodniejszy od poprzedniego, przede wszystkim czcionki w tym formacie są
bardzo rozpowszechnione, do dyspozycji mamy tysiące krojów. Tekst wektorowy może
być obrócony o dowolny kąt, jest wygładzony, nie ma większych problemów z
uzyskaniem nietypowych znaków, w tym polskich liter. Wadą tekstu wektorowego jest
większe zużycie zasobów i czas generacji tekstu, jednak dla współczesnych komputerów
nie są to duże wymagania. Biblioteka FreeType2, z której PHP korzysta przy obsłudze
czcionek TrueType, jest napisana bardzo oszczędnie. Druga wada to fakt, że nie w każdej
instalacji PHP + GD obsługa czcionek TT jest dostępna.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
imagefttext($obrazek, $rozmiar, $kąt, $x, $y, $kolor, $czcionka, $tekst);
(0, 0)
y
x
Ja
t
s
k
e
t
ś
ki
linia bazowa
kąt
Dodatkowo można podać funkcji tablicę opcji, z których użyteczną jest opcja zmiany
odstępu między liniami.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
8.4. Tekst, a sprawa polska
Polskie litery (a także inne znaki specjalne) można podać w łańcuchu korzystając z tego,
że jest on zakodowany w UTF-8 (a więc można w nim umieścić dowolny znak Unicode).
Korzysta się z tej możliwości podając znaki w zapisie ósemkowym. Oto przykład:
imagefttext($obrazek, 16, 0, $x, $y, $kolor, "Arial.ttf",
"\305\274\303\263\305\202w");
Przykład ten wypisze na obrazku słowo „żółw”. Dla wygody zamieściłem poniżej tabelę
podającą ósemkowe kody polskich liter w UTF-8. Oczywiście w przypadku większej ilości
tekstu można sobie pracę zautomatyzować, zrzucając zamianę liter na kody na PHP. W
ten sposób (podając kody UTF-8) można uzyskać dowolny znak Unicode, oczywiście pod
warunkiem, że znak ten zawarty jest w czcionce.
ą
ć
ę
ł
ó
ń
ś
ź
ż
\304\205
\304\207
\304\231
\305\202
\303\263
\305\204
\305\233
\305\272
\305\274
Ą
Ć
Ę
Ł
Ó
Ń
Ś
Ź
Ż
\304\204
\304\206
\304\230
\305\201
\303\223
\305\203
\305\232
\305\271
\305\273
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
8.5. Rozmiary tekstu
Bardzo często potrzebujemy rozmiarów tekstu, zanim go na obrazku umieścimy (np. w
celu wycentrowania, czy też wyrównania do prawej). Służy do tego (ale tylko dla tekstu z
czcionek TrueType) funkcja imageftbbox(). Oto jak należy ją wywoływać:
$box = imageftbbox($rozmiar, $kąt, $czcionka, $tekst);
gdzie:
●
$rozmiar – rozmiar czcionki,
●
$kąt – kąt nachylenia napisu, jak w imagefttext(),
●
$czcionka – ścieżka dostępu do pliku z czcionką, jak w imagefttext(),
●
$tekst – łańcuch tekstowy do wydrukowania.
Wynikiem jest ośmioelementowa tablica, zawierająca następujące dane:
0, 1 => lewy dolny róg tekstu (x, y)
2, 3 => prawy dolny róg tekstu (x, y)
4, 5 => prawy górny róg tekstu (x, y)
6, 7 => prawy dolny róg tekstu (x, y)
Współrzędne są odniesione do punktu początkowego tekstu (na linii bazowej), wyrażone
są w pikselach. Warto zauważyć, że są to narożniki prostokąta otaczającego konkretny
podany tekst, a więc np. wysokość tego prostokąta może być różna dla różnych tekstów
pisanych tę samą czcionką (krój i rozmiar).
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
8.6. Linie niekoniecznie ciągłe
Oprócz rysowania linii ciągłych, biblioteka GD umożliwia rysowanie linii dowolnym
wzorem kolorów. W tym celu definiujemy tablicę zawierającą numery kolorów kolejnych
stawianych w linii pikseli. W momencie dojścia do końca tablicy, zaczynamy czytanie
kolorów pikseli od początku. Oto przykład, linia kropkowana na przemian kolorem
czerwonym i białym:
$cz = imagecolorallocate($obrazek, 255, 0, 0);
$bi = imagecolorallocate($obrazek, 255, 255, 255);
$wzorek = array($cz, $bi);
Mamy zdefiniowane kolory, oraz tablicę – na przemian będą powtarzane piksele
czerwone i białe.
imagesetstyle($obrazek, $wzorek);
Ustawiamy styl (zdefiniowany tablicą) dla obrazka. Teraz linie tym stylem możemy
rysować używając specjalnego numeru „koloru” – IMG_COLOR_STYLED.
imageline($obrazek, 50, 60, 90, 200, IMG_COLOR_STYLED);
Jeżeli potrzebujemy więcej styli, możemy zdefiniować wiele tablic i zmieniać je
wywołując imagesetstyle() według potrzeb.
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
8.7. Linie rysowane fragmentem obrazka
To kolejna
obrazkiem
nakładać).
obrazkiem
możliwość wzbogacenia grafiki. Każdy piksel linii może być zastąpiony
(w przypadku linii ciągłej kopie obrazka będą się na siebie oczywiście
Obrazek może być załadowany z pliku, lub wygenerowany. Oto przykład, z
wygenerowanym. Będzie on miał postać małego kółka.
$kolko = imagecreatetruecolor(9, 9); // obrazek 9 x 9
$niebieski = imagecolorallocate($kolko, 0, 100, 255);
imagefilledellipse($kolko, 5, 5, 9, 9, $niebieski);
Teraz użyjemy tego kółka jako obrazka do rysowania linii:
imagesetbrush($obrazek, $kolko);
imageline($obrazek, 20, 20, 160, 160, IMG_COLOR_BRUSHED);
Efekt jest nieco różny od oczekiwanego, ale wynika z faktu, że kółko brane jest wraz z
czarnym tłem, a więc de facto rysujemy kwadratem. Aby uzyskać spodziewany efekt,
należy uczynić czarny kolor w brushu przeźroczystym, umieszczając zaraz po instrukcji
rysowania koła:
$czarny = imagecolorallocate($kolko, 0, 0, 0);
imagecolortransparent($kolko, $czarny);
mgr inż. Grzegorz Kraszewski – TECHNOLOGIE INTERNETOWE 3 – wykład 8: „Generowanie grafiki, cz. 2”.
Jeżeli nie chcemy nakładających się obrazków, można połączyć możliwość używania
brushy i wzorków. W takim przypadku każdy piksel zdefiniowany jako czarny (0, 0, 0),
oznacza niepostawienie obrazka w miejscu piksela, każdy piksel różny od czarnego, to
postawienie obrazka. Oprócz tego używamy specjalnego numeru „koloru” –
IMG_COLOR_STYLEDBRUSHED. Oto przykład, nasze kółeczko stawiamy na co 10 pikselu
– dzięki temu poszczególne kółka nie będą się na siebie nakładały:
$czarny = imagecolorallocate($obrazek, 0, 0, 0);
$jakis = imagecolorallocate($obrazek, 72, 43, 182);
$wzorek = array($jakis, $czarny, $czarny, $czarny, $czarny, $czarny,
$czarny, $czarny, $czarny, $czarny);
imagesetstyle($obrazek, $wzorek);
imagesetbrush($obrazek, $kolko);
imageline($obrazek, 20, 20, 160, 160, IMG_COLOR_STYLEDBRUSHED);