Autor: Marek REGGI Reinowski

PHP już od dawna dostarcza funkcji graficznych. Dokładniej – dostarczają ich zewnętrzne biblioteki, jak gd (obsługa plików w formacie JPEG, PNG, WBMP) czy ming (obsługa filmów Macromedia Flash – SWF). Dzięki nim mamy możliwość generowania wykresów, obróbki zdjęć itp.

Oczywiście nie ma mowy o żadnych zaawansowanych operacjach. Przede wszystkim dlatego, że PHP jako język interpretowany, jest stosunkowo powolny w działaniu. Dlatego też nie opłaca się przeprowadzać skomplikowanych operacji na obrazie. Po pierwsze czas trwania obliczeń może przekroczyć maksymalny czas przeznaczony na wykonanie skryptu (ustala się to w pliku php.ini za pomocą zmiennej max_execution_time w sekcji Resource Limits), który standardowo wynosi 30 sekund. Po drugie – nawet jeśli ww. zmiennej zostanie przypisana wartość pozwalająca na wykonanie się skryptu, to gość serwisu nie będzie z pewnością czekał kilku minut na każdą grafikę.

Dlatego też obróbka grafiki powinna ograniczyć się do niezbędnego minimum. Najczęściej wykorzystuje się funkcje graficzne do generowania różnego rodzaju wykresów, obrazków liczników odwiedzin, statystyk itp. Często wykorzystywaną funkcją jest też tworzenie miniaturek plików, np. w galeriach zdjęć itp.

W niniejszym artykule opiszę kilka możliwości wykorzystania funkcji dostępnych dzięki wykorzystaniu biblioteki gd. Jeśli nie została ona włączona, należy to zrobić odkomentowując linię ;extension=php_gd.dll w pliku php.ini. Należy tez się upewnić, czy zmienna extension_dir w tym pliku wskazuje na faktyczny katalog, w którym są umieszczone biblioteki dodatkowe. Jeśli wszystko się zgadza, funkcje graficzne powinny być dostępne.

Angielskie nazwy zmiennych

Będę używał nazw pochodzenia angielskiego. Nie dlatego bynajmniej, że staram się na siłę operować tym językiem. Po prostu jest to praktyczne – język angielski jest w powszechnym użyciu na świecie, a szczególnie w informatyce. Dzięki takiemu podejściu każdy programista (choćby pochodził z Chin szybciej zrozumie co robi dana funkcja, jakich danych spodziewać się w zmiennej itp. Trudno się spodziewać, żeby znał język polski.

Klasy i metody

Aby jak najłatwiej można było operować na obrazach, wszystkie funkcje zostaną zawarte w dwóch klasach. Klasy są zbiorami opisów – funkcji (nazywanych metodami), i zmiennych (właściwości). Same klasy jednak nie zawierają danych – są tylko opisem, na którego podstawie tworzy się obiekty. Dzięki temu możemy łatwo operować na wielu obiektach utworzonych na podstawie klas. Klasy zostaną umieszczone w pliku img.class.php (listing 1.).

Klasa image i konstuktor klasy – image()

Pierwsza klasa, o nazwie image (Listing 1., wiersz 2.) będzie tworzyła i przechowywała obrazek, dane o jego formacie i wielkości, a także będzie go wysyłać do przeglądarki. Zrealizowane jest to za pomocą trzech metod.

Metoda image() jest konstruktorem klasy. Oznacza to, iż jest ona wywoływana w momencie utworzenia obiektuna podstawie danej klasy. Dzięki temu mamy możliwość ustawienia początkowych zmiennych itp. Metoda ta posiada jeden argument – $format. Argument ten nie jest obowiązkowy, to znaczy, iż w wywołaniu metody można go pominąć, a wtedy zostanie mu przypisana wartość domyślna. W naszym wypadku jest to wartość „jpeg” zapisana po znaku równości w deklaracji funkcji. Właściwość ta jest wykorzystywana już w momencie tworzenia obiektu, gdy tworząc go, nie podamy żadnych wstępnych parametrów – w takim wypadku domyślnym formatem będzie „jpeg.

W wierszu 6. wartość zmiennej $format zostaje przypisana do właściwości obiektu – $this->img_format. Słowo kluczowe this używane jest w celu identyfikacji klasy, podpowiedzenia PHP, że chodzi nam o metodę, bądź właściwość tej właśnie klasy, na podstawie której jest utworzony obiekt. Dzięki temu będzie również możliwość odwoływania się do danej właściwości spoza klasy – o tym później.

W wierszu 7, za pomocą funkcji strtolower() wszystkie litery w ciągu zawartym we właściwości $this->img_format zostają zamienione na małe litery. Należy to zrobić, ponieważ później będziemy wykorzystywać tę zmienną przy generowaniu obrazka i wybieraniu odpowiednich funkcji za pomocą instrukcji switch(), w której wielkość liter ma znaczenie. Drobny błąd w wywołaniu metody (podanie argumentu wielkimi literami) spowodowałby błędy.

Utworzenie nowego obrazka i pobranie jego właściwości – metoda image_new_from()

Metoda image_new_from() posiadająca jeden argument (wiersz 10.) tworzy nowy obrazek. Argumentem jest nazwa pliku obrazka, który chcemy poddać obróbce.

W wierszu 11. zostaje sprawdzone, czy obrazek istnieje na dysku. Jeśli tak, to wykorzystując instrukcją sterującą switch() i znanego już formatu pliku, wybieramy instrukcję, która utworzy nowy obrazek. Tutaj mamy dwie możliwości. Jeśli właściwość $this->img_format zawiera ciąg „png”, wywołana zostanie funkcja ImageCreateFromPNG() (wiersz 17.). W przeciwnym wypadku zostanie wywołana funkcja ImageCreateFromJPEG() (wiersz 18.). Funkcje, jak można się zorientować po nazwie pliku, tworzą nowy obrazek na podstawie pliku o nazwie podanej jako argument. Funkcje zwracają identyfikator obrazka, podobnie jak ma to miejsce w przypadku funkcji fopen() przy otwieraniu plików. Identyfikator ten zostaje przypisany do właściwości obiektu – $this->img.

Jeśli plik o podanej nazwie nie istnieje, tworzony jest nowy, pusty obrazek o wymiarach 100×50 pikseli (wiersz 25.).

W wierszach 27. i 28. do właściwości $this->img_w i $this->img_h zapisywane są odpowiednio szerokość i wysokość obrazka. Zrealizowane jest to za pomocą funkcji ImageSX() i Image SY(). Argumentem obu funkcji jest identyfikator obrazka zawarty we właściwości $this->img.

Wysyłanie obrazka – metoda send()

Kolejną metodą umieszczoną w klasie image jest send() (wiersz 31.). Metoda ta wysyła do przeglądarki nagłówek HTTP informujący ją, iż powinna się spodziewać pliku graficznego. Następnie za pomocą instrukcji sterującej switch(), na podstawie wartości właściwości $this->img_format wybieramy funkcję, która wyśle obrazek do przeglądarki.

Tworzenie obiektu na podstawie klasy

W tym momencie można już korzystać z obiektów utworzonych na podstawie klasy image. W tym celu utworzymy nowy plik o nazwie img.php (Listing 2.). W linii 2. za pomocą funkcji include() dołączamy plik zawierający klasę image. Następnie w wierszu 3. tworzymy nowy obiekt za pomocą instrukcji new na podstawie klasy image. Obiekt zostanie przypisany do zmiennej $my_image. W wierszu 4. wywołujemy metodę nowoutworzonego obiektu – $my_image->img_new_from() z parametrem zawierającym nazwę pliku. Następnie w wierszu 5. wysyłamy nagłówek HTTP i obrazek za pomocą metody $my_image->send().

Dziedziczenie własności i metod – klasa filters

W ten sposób przygotowaliśmy sobie grunt do obróbki obrazka – możemy już go utworzyć z pliku i wysłać w formacie PNG lub JPEG. Możemy więc napisać funkcje przekształcające obrazek. Zostaną one umieszczone w drugiej klasie zawartej w pliku img.class.php. Klasa będzie nosiła nazwę filters. Ale to nie wszystko – po nazwie klasy występuje słowo kluczowe extends i nazwa klasy – image. Oznacza to, iż klasa filters jest rozszerzeniem klasy image i dziedziczy po niej wszystkie właściwości i metody, czyli można z nich korzystać tak, jakby były zawarte w klasie filters.

Napiszemy trzy filtry do wykorzystania w obróbce obrazków. Będą się one zawierały w metodach border_blur() (ramka utworzona z rozmycia obrazka), border_blend() (ramka powstała na skutek „wtopienia” obrazka w tło) i thumb() (miniatura obrazka).

Określanie współrzędnych rogów danego obrazka

Pierwszą metodą klasy filters będzie metoda corners() (Listing 1., wiersz 47.) posiadająca argument będący grubością ramki tworzonej przez metody border_blur() i border_blend(), z których to będzie ona wywoływana. Jej zadaniem będzie tworzenie tablicy właściwości $this->corner (wiersze 49.-52.). Cztery pierwsze elementy tej tablicy zawierają odpowiednio współrzędne x i y piksela od którego ma się zacząć przetwarzanie obrazka i piksela, na którym ma się skończyć. Piąty i szósty element zawierają krok, czyli liczbę określającą, co który piksel i w którą strona ma zostać poddany obróbce. Element piąty odnosi się do kroku w poziomie (1 oznacza krok w prawo, 1- oznacza krok w lewo), element szósty odnosie się do kroku w pionie (1 – w dół, -1 w górę). Określenie kierunku kroku będzie potrzebne przy tworzeniu wtopienia, ponieważ ważny jest tu kierunek wtapiania.

RAMKA ROZMYTA – metoda border_blur()

Kolejną metoda zdefiniowaną w klasie filters jest border_blur(). Posiada ona dwa argumenty – $bord (określenie grubości ramki w pikselach) i $blur (określenie stopnia rozmycia obrazu na ramce). Rozmycie będzie realizowane w najprostszy sposób – pobrane zostaną wartości kolorów z pikseli oddalonych od aktualnie obrabianego piksela o jeden i więcej pikseli (największa odległość określona jest właśnie jako wartość argumentu $blur).

W wierszu 57. wywoływana jest opisana wyżej metoda $this->corners.

Następnie w wierszu 59. uruchamiamy pętlę, w której będziemy pobierać i przekształcać kolory obrazka. Jej licznik – $corn, będzie określać pierwszy indeks elementu tablicy $this->corner, w której zawarte są współrzędne rogów obrazka.

W pętli tej występują kolejne pętle, które będą określać piksel przeznaczony do obróbki. Pętla uruchomiona w wierszu 61. określa współrzędne poziome kolejnych pikseli (a dokładniej – określa to wartość licznika), pętla w wierszu określa analogicznie współrzędne pionowe. Wartość początkowa, końcowa oraz krok w obu tych pętlach będzie pobierana z tablicy $this->corner.

W wierszu 65. zostaje przypisana początkowa wartość zero do zmiennej $colors_num. Zmienna ta będzie używana do określenia liczby pikseli, których kolory weszły w skład aktualnie obrabianego piksela.

W wierszu 66. do zmienne $r, $g i $b zostają wyzerowane.

Następnie w wierszu 67. zostaje uruchomiona pętla, której zadaniem będzie określenie współrzędnej poziomej piksela, z którego ma zostać pobrana wartość koloru. Wartość przesunięcia będzie się zawierała w granicach od -$blur do +$blur, czyli zostaje określona za pomocą argumentu przekazanego w wywołaniu metody. W wierszu 69. do zmiennej $px przypisywana jest wartość współrzędnej tego piksela obliczona na podstawie wartości współrzędnej aktualnie obrabianego piksela (zmienna $x) i aktualnego przesunięcia (zmienna $x1). Następnie sprawdzane jest, czy wartość współrzędnej tego piksela nie jest mniejsza od zera, bądź nie jest większa od szerokości obrazu, co spowodowałoby błąd przy pobieraniu wartości koloru z piksela, który nie istnieje (wiersz 69.) Analogicznie w wierszach 72.-75. uruchamiana jest pętla i sprawdzany warunek dla współrzędnej pionowej.

Pobranie wartości koloru w określonym punkcie funkcje ImageColorAt() i ImageColorsForIndex()

Jeśli wszystkie warunki są spełnione, to znaczy, że współrzędne zawarte w zmiennych $px i $py mieszczą się w granicach obrazka i można pobrać wartości kolorów z danego piksela. Zostanie to zrealizowane w wierszach 77.-82. Funkcja ImageColorAt() zwraca indeks koloru piksela określonego za pomocą współrzędnych przekazanych jako parametry wywołania funkcji – kolejno identyfikator obrazka, współrzędna pozioma i pionowa. Następnie w wierszu 78. funkcja ImageColorsForIndex() tablicę asocjacyjną, która zostanie zapisana w tablicy $img_pixel_colors. Jej poszczególne elementy zawierają wartości składowych koloru – R, G i B. Elementy te mają indeksy „red”, „green” i „blue”. Argumentami funkcji są identyfikator obrazka i indeks koloru w tym obrazie.

W wierszach 80.-82. do zmiennych $r, $g i $b dodawane są wartości odpowiednich elementów tablicy $img_pixel_colors. Następnie inkrementowana jest wartość zmiennej $colors_num. Dzięki temu znana jest liczba wartości kolorów, jaka złożyła się na daną wartość.

Gdy wartości kolorów wszystkich pikseli okalających aktualnie obrabiany piksele zostaną zliczone (to znaczy, gdy wykonają się pętle uruchomione w wierszach 67. i 72.) sprawdzana jest wartość zmiennej $colors_num, a jeśli nie zawiera różnej od zera, przypisywana jest jej wartość równa jeden. Następnie poszczególne składowe koloru dzielone są przez ilość dodanych wartości i w ten sposób obliczany jest średni kolor z zadanego obszaru.

Określenie indeksu koloru w palecie i zapisanie go do piksela – funkcje ImageColorResolve() i ImageSetPixel()

W wierszu 92. za pomocą funkcji ImageColorResolve() określony zostaje indeks koloru z palety kolorów danego obrazka, który najlepiej pasuje do koloru podanego jako kolejne argumenty wywołania funkcji.

Następnie wartość ta jest zapisywana do obrazu za pomocą funkcji ImageSetPixel() w punkcie o przekazanych współrzędnych.

Po przejściu wszystkich pętli w pamięci serwera cały obrazek jest otoczony ramką o grubości przekazanej jako parametr $bord i stopniu rozmycia przekazanym jako $blur. Należy szczególnie uważać na wielkość argumentu $blur, gdyż ilość wykonań pętli, a tym samym ilość obliczeń dla jednego piksela (ilość pikseli, których kolory będą się składały na kolor aktualnego piksela) zależy właśnie od niego i wynosi (2*$blur+1)2. Jak łatwo obliczyć, dla $blur = 1 będzie to w sumie 9 pikseli, dla $blur = 3 ilość składowych wynoci 49 (czyli jeszcze niewiele), ale już dla $blur = 10 będzie to 441 składowych. Mnożąc to przez liczbę pikseli widać, jak wielką pracę musi wykonać serwer.

RAMKA WTOPIONA W TŁO – metoda border_blend()

Kolejnym efektem, jaki zostanie umieszczony w tej klasie będzie tworzenie ramki powstałej wskutek wtopienia w tło krawędzi obrazka. Zrealizowane to będzie w metodzie border_blend() (wiersz 100.). Będzie ona posiadała cztery argumenty: $bord – grubość wtopienia (grubość ramki) oraz $r, $g, $b – składowe koloru, w który będzie wtapiany obrazek.

Podobnie jak w metodzie $border_blur(), tutaj w wierszu 101 wywoływana jest metoda corners().

W wierszu 106 do tablicy $sinus przypisywane są w pętli wartości sinusa obliczone za pomocą funkcji sin() tak, aby dla elementu o indeksie równym zero była to wartość sin (0 rad.) , czyli sinus kąta 0 stopni, a dla elementu o największym indeksie (który będzie określony za pomocą zmiennej $bord) została przypisana wartość sin(PI/2 rad.), czyli sinus kąta 90 stopni. Funkcja deg2rad() zamienia wartość wyrażoną w stopniach na wartość wyrażoną w radianach, której wymaga funkcja sin().

Następnie pętle zainicjowane w wierszach 110. i 112. pobierają kolejne wartości kolorów pikseli za pomocą funkcji ImageColorAt() i ImageColorsForIndex(), podobnie jak w przypadku metody border_blur().

Wybór kierunku wtapiania ramki

W wierszu 116. występuje instrukcja warunkowa switch(). Jej argument (licznik pętli $corn) określa, która część obrazu jest w danej chwili obrabiana (górna, lewa, prawa, czy dolna). Dokładniej rzecz ujmując licznik $corn określa element tablicy właściwości $this->corner zawierającej współrzędne początku i końca zakresu obrabiania obrazu, a na tej podstawie wiadomo która część obrazu jest aktualnie obrabiana. Jeśli się przeanalizuje zawartość elementów ww. tablicy, to łatwo zauważyć iż zawiera ona wartości odpowiednio dla obszarów: górnego, lewego, dolnego oraz prawego. Jest to bardzo ważne, gdyż ramka musi zostać wtopiona dla każdego z tych obszarów inaczej:

  • dla górnego – z góry na dół,
  • dla lewego – z lewej do prawej,
  • dla dolnego – z dołu do góry,
  • dla prawego – z prawej do lewej.

Dzięki określeniu kierunku kroku w elementach 5. i 6. tablicy $this->corner , pętle będą pobierały piksele we właściwej kolejności. Zmienna $alpha będzie zawierała stosunek oryginalnego koloru do koloru wtapiania.

Następnie w wierszach 131.-133. wartości składowych koloru oryginalnego danego piksela i koloru wtapiania są dodawane do siebie w proporcjach określonych właśnie za pomocą zmiennej $alpha – im bliżej do brzegu obrazu, tym mniej dodawane jest z oryginalnego obrazu, a więcej z koloru wtapiania. W ten sposób powstanie delikatne, gradientowe wtopienie.

W wierszach 134. i 135. obliczana jest wartość indeksu dla danego koloru i kolor ten zapisywany jest w odpowiednim miejscu obrazu – identycznie jak w metodzie border_blur().

MINIATURKA – metoda thumb()

Bardzo często zadawane jest pytanie, jak wykonać miniaturki obrazków, tak by można z nich było stworzyć na przykład podgląd właściwych obrazków w galerii zdjęć itp. Możliwość taką da nam metoda thumb() (wiersz 141), którą za chwilą napiszemy. Posiada ona jeden argument $y – wysokość miniaturki, który na dodatek nie jest obowiązkowy. Jeśli go nie podamy w wywołaniu metody, przyjęta zostanie wartość 60. Dlaczego tylko wysokość, a nie szerokość? Przyjąłem tak dla ułatwienia – przeważnie galeria obrazków to jest tabelka w HTMLu, w której umieszczone są podglądy będące odnośnikami do właściwych obrazów. Różna szerokość miniatur nie razi tak bardzo, jak różna wysokość, gdyż obrazki poukładają się w równe wiersze.

reggi_php_5_4

W wierszu 143. obliczana jest szerokość miniatury i wynik zapisywany jest do zmiennej $x. Wynik wyrażenia jest zaokrąglany za pomocą funkcji round() do najbliższej liczby całkowitej. W kolejnym wierszu tworzony jest obrazek o wysokości podaje w argumencie i obliczonej przed chwilą szerokości.

W wierszu 145. funkcja ImageCopyResized() kopiuje zawartość oryginalnego obrazka do miniatury, skalując go jednocześnie.

Następnie wskaźnik miniaturki zapisywany jest do wskaźnika oryginalnego obrazu i w ten sposób oryginalny obrazek zostaje zastąpiony miniaturką. W wierszach 147. i 148. do właściwości określających wysokość i szerokość obrazka zapisywane są nowe wartości, odpowiednie dla miniaturki. W ten sposób przygotowujemy się na ewentualne użycie metod border_blur() i border_blend() na miniaturze.

Praktyczne użycie filtrów

Teraz można użyć już wszystkich filtrów. W tym celu dodajemy wywołania metod w pliku img.php (listing 3.). Możesz poeksperymentować z ustawieniami argumentów. Należy pamiętać, iż dwa pierwsze filtry nie nadają się do użycia w sieci – są po prostu zbyt powolne. Natomiast trzeci jak najbardziej może być używany (sam go używam w moich projektach), gdyż w stosunkowo niewielkim stopniu obciąża serwer.

reggi_php_5_5

Marek REGGI Reinowski

LISTINGI:

<? 
class image { 
function image($format="jpeg") { 
    $this->img_format = $format; 
    $this->img_format = strtolower($this->img_format); 
} 

function img_new_from ($name) { 
  if (file_exists($name)) { 
     switch ($this->img_format) { 
        case "png": $this->img = imageCreateFromPNG ($name); break; 
        default: $this->img = imageCreateFromJPEG ($name); 
     } 
  } 
  else { 
    $this->img = imageCreate(100, 50); 
  } 
  $this->img_w = imageSX($this->img); 
  $this->img_h = imageSY($this->img); 
} 

function send() { 
   header ("Content-type: image/" . $this->img_format); 
   switch ($this->img_format) { 
      case "png": ImagePNG ($this->img); break; 
      default: ImageJPEG ($this->img); 
   } 
} 
} 

class filters extends image { 

function corners ($bord) { 
  $this->corner[0] = Array(1 => 0, 0, $this->img_w, $bord, 1, 1); 
  $this->corner[1] = Array(1 => 0, 0, $bord, $this->img_w, 1, 1); 
  $this->corner[2] = Array(1 => 0, $this->img_h, $this->img_w, $this->img_h-$bord-1, 1, -1); 
  $this->corner[3] = Array(1 => $this->img_w, 0, $this->img_w-$bord-1, $this->img_h, -1, 1); 
} 

function border_blur ($bord, $blur) { 
  $this->corners($bord); 
  for ($corn=0;$corn<4;$corn++) { 
     for ($x=$this->corner[$corn][1];$x!=$this->corner[$corn][3];$x+=$this->corner[$corn][5]) { 
         for ($y=$this->corner[$corn][2];$y!=$this->corner[$corn][4];$y+=$this->corner[$corn][6]) { 
             $colors_num=0; 
             $r=$g=$b=0; 
             for ($x1=-$blur;$x1<$blur+1;$x1++) { 
                 $px = $x+$x1; 
                  if ($px>=0 & $px<$this->img_w) { 
                    for ($y1=-$blur;$y1<$blur+1;$y1++) { 
                        $py = $y+$y1; 
                        if ($py>=0 & $py<$this->img_h) { 
                           $color_index = ImageColorAt($this->img, $px, $py); 
                           $img_pixel_colors = ImageColorsForIndex($this->img, $color_index); 
                           $r += $img_pixel_colors["red"]; 
                           $g += $img_pixel_colors["green"]; 
                           $b += $img_pixel_colors["green"]; 
                           $colors_num++; 
                       } 
                    } 
                 } 
              } 
              if (!$colors_num) $colors_num=1; 
              $r /= $colors_num; 
              $g /= $colors_num; 
              $b /= $colors_num; 
              $img_color = ImageColorResolve($this->img, $r, $g, $b); 
              ImageSetPixel ($this->img, $x, $y, $img_color); 
           } 
       } 
    } 
} 

function border_blend ($bord, $r_blend, $g_blend, $b_blend) { 
    $this->corners($bord); 
    for ($i=0;$i<=$bord;$i++) { 
        $sinus[$i] = sin(deg2rad(90/$bord*$i)); 
    } 
    for ($corn=0;$corn<4;$corn++) { 
        for ($x=$this->corner[$corn][1];$x!=$this->corner[$corn][3];$x+=$this->corner[$corn][5]) { 
            for ($y=$this->corner[$corn][2];$y!=$this->corner[$corn][4];$y+=$this->corner[$corn][6]) { 
                $color_index = ImageColorAt($this->img, $x, $y); 
                $img_pixel_colors = ImageColorsForIndex($this->img, $color_index); 
                switch ($corn) { 
                    case 0: $alpha=$sinus[$y]; break; 
                    case 1: $alpha=$sinus[$x]; break; 
                    case 2: $alpha=$sinus[$this->img_h-1-$y]; break; 
                    case 3: $alpha=$sinus[$this->img_w-1-$x]; break; 
                } 
                $r = $img_pixel_colors["red"] * $alpha + $r_blend * (1-$alpha); 
                $g = $img_pixel_colors["green"] * $alpha + $g_blend * (1-$alpha); 
                $b = $img_pixel_colors["blue"] * $alpha + $b_blend * (1-$alpha); 
                $img_color = ImageColorResolve($this->img, $r, $g, $b); 
                imagesetpixel ($this->img, $x, $y, $img_color); 
            } 
         } 
     } 
} 

function thumb ($y = 60) { 
    $x = round($this->img_w / $this->img_h * $y); 
    $this->img_thumb = ImageCreate($x, $y); 
    ImageCopyResized($this->img_thumb, $this->img, 0, 0, 0, 0, $x, $y, $this->img_w, $this->img_h); 
    $this->img = $this->img_thumb; 
    $this->img_w = $x; 
    $this->img_h = $y; 
} 

} 

?> 

Listing 2: img.php – pierwsza wersja

<? 
include("img.class.php"); 
$my_image = new image; 
$my_image->img_new_from("reggi.jpg"); 
$my_image->send(); 
?> 

Listing 3. img.php – wersja z wywołaniami wszystkich metod

<? 
include("img.class.php"); 
$my_image = new filters; 
$my_image->img_new_from("reggi.jpg"); 
$my_image->thumb(); 
$my_image->border_blend(10, 255, 255, 255); 
$my_image->border_blur(10, 2); 
$my_image->border_blend(1, 127, 127, 127); 
$my_image->send(); 
?>

Niniejszy artykuł pochodzi z zeszytu CHIP Special, nr 8, (56) Grudzień 2001 – „Tworzenie stron WWW” autorstwa Marka Reinowskiego. Opublikowano za zgodą wydawnictwa Vogel Burda Communications

Pajączek.pl - twórz poprawiaj publikuj