Medvědi.htm

php obsahuje několik možností pro zpracování grafiky, nejběžnější je použití knihovny GD.

Postup je takový, že si nejprve vytvoříme virtuální obrázek - buď prázdný, například funkcí imagecreatetruecolor (nutno zadat rozměry), nebo vyjdeme z nějakého již existujícího obrázku, pak můžeme použít například funkci imagecreatefrom jpeg. Ve druhém případě ale musíme použít funkci (či spíše direktivu) @, která nám místo hodnoty vrátí odkaz (resource), protože mít v proměnné celý obrázek by bylo poněkud nemotorné (a hlavně, funkce s tím nepočítají). Pro obrázek je v paměti rezervováno místo, odpovídající jeho rozměrům a barevné hloubce; pokud nakreslíme cokoli mimo tyto meze (část kružnice apod.), je to ignorováno, ale nemělo by to způsobit problémy se zápisem do jiné než vyhrazené paměti, jako je tomu u některých jiných programovacích jazyků.

Na obrázek si můžeme jakkoli čmárat, psát texty a podobně. Pozor, tohle všechno se děje s virtuálním obrázkem někde na serveru, zatímco uživatel marně čeká, že dostane svou html stránku. Taktéž pozor při popisech, musíme vybírat z fontů, které jsou k dispozici na serveru, jen nevím, jak zjistit, které to jsou.

Když je obrázek hotový, můžeme jej například uložit do souboru, například příkazem imagejpeg, imagegif či imagepng, kde je třeba zadat jméno souboru. Tento obrázek můžeme následně použít na naší webové stránce. Vzhledem k tomu, že s odesláním výsledku php se na většině serverů čeká, než se sestaví celý soubor, pak dokonce na téže, která obrázek generuje.

Zvláštním případem je vytvořit pomocí php přímo obrázek (místo html). Tímto způsobem budeme vytvářet obrázky v tomto a navazujícím cvičení. Pokud tento php skript vyvoláme, zobrazí se nám jen výsledný obrázek; dokonce si jej můžeme přidat na svou html či php stránku běžným způsobem:

<img src="ukazka.php">

Následující ukázka je ze serveru php.net/manual. Pokud má být výstupem php skriptu obrázek, pak skript nejen že nesmí obsahovat příkazy jako echo a print, ale také je třeba zaměnit http hlavičku (viz protokol http 1.1). To uděláme tak, že před generováním obrázku zavoláme funkci header a serveru podstrčíme jiný parametr Content-Type (default, tedy pokud neřekneme jinak, je text/html). Musí samozřejmě korespondovat s funkcí, normálně určenou pro ukládání obrázků na serveru (v této ukázce je to formát png, v další jpeg).

Jazyk php a knihovna GD vznikly v době, kdy ještě převažovaly obrázky s 256 barvami a barevnou paletou, tomu odpovídá, že každou barvu musíme nejprve deklarovat. Proto také je v knihovně tolik funkcí, začínajících imegecolor. Složky v použité funkci imagecolorallocate jsou v pořadí R,G,B, zde jsou zadány v hexu (zápis 0x znamená, že následující jedna či více číslic je hexadecimální, tj. od nuly do F). 0x00 znamená zhasnutý paprsek, 0xFF plně rozsvícený (také lze psát 255).

<?php
// Vytvoření obrázku o rozlišení 200x100 bodů
$im imagecreatetruecolor(200100);

// Příprava barev pro kreslení
$white imagecolorallocate($im0xFF0xFF0xFF);
$black imagecolorallocate($im0x000x000x00);

// Vybarvení pozadí bílou - použije se velký plný obdélník
imagefilledrectangle($im0029999$white);

// Nastavení tloušťky pro čárové objekty na 5
imagesetthickness($im5);

// Vykreslení (čárového) obdélníku
imagerectangle($im141418585$black);

// Výstup obrázku - bez udání jména přímo do prohlížeče
header('Content-Type: image/png');
imagepng($im);

// Vrácení paměti
imagedestroy($im);
?> 

Všimněte si, že názvy většiny funkcí knihovny GD začínají slovem image. Také si všimněte, že při volání funkce zpravidla musíme jako první parametr uvést proměnnou typu "resource", obsahující odkaz na obrázek, a to i tam, kde se zdánlivě s obrázkem nic neděje (imagecolorallocate) - ve skutečnosti je použit objektový přístup a parametry jako barvevná paleta, tloušťka pera či druh čáry jsou součástí obrázku, byť se s ním například při použití příkazu imagejpeg v následujícím skriptu již neexportují.

Možnost vyjít z nějakého již existujícího obrázku ukazuje následující skript. Pokud si jej budete chtít vyzkoušet, musíte použít nějaký obrázek (testováno s obrázkem s medvědy), a zkopírovat si jej na server, který používáte (také lze obrázek vytvořit z jiného, zadaného jako url). Vyvoláme jej například:

<img src="bears.php">

Následuje bears.php:

<?php
header('Content-Type: image/jpeg');
$img = @imagecreatefromjpeg('bears.jpg');
$tmp = imagecreatetruecolor(320,200);
imagecopyresampled($tmp,$img,0,0,0,0,320,200,imagesx($img),imagesy($img));
imagejpeg($tmp);
imagedestroy($img);
imagedestroy($tmp);
?>

Hlavička souboru je až uvnitř php. Na dalších řádcích jsou vytvořeny dva dočasné obrázky (v paměti serveru). Funkcí imagecopyresampled je obsah jednoho zkopírován do druhého (podotýkám, že je změněna velikost - funkce umí zvětšovat i zmenšovat). Funkce imagejpeg bez udání výstupího souboru vytvoří právě obrázek, který se přímo zobrazí (na straně klienta). Volání imagedestroy na oba obrázky vrátí alokovanou paměť - je to spíše slušnost, časem by se systému vrátila sama (je to, jako když po sobě při odchodu uklidíte). Funkce imagesx, resp. imagesy vrací rozměry obrázku.

Mám ještě jednu ukázku, kde obrázek se nejen zobrazí, ale také uloží do souboru:

<?php
header('Content-Type: image/jpeg');
$src = @imagecreatefromjpeg("data/".$file);
$dst = imagecreatetruecolor(100,75);
imagecopyresampled($dst, $src, 0, 0, 0, 0, 100, 75, imagesx($src), imagesy($src));
imagejpeg($dst,"data/".$file,60);
imagejpeg($dst);
imagedestroy($dst);
imagedestroy($src);
?> 

Zmenší obrázek, který již předem musí být v adresáři data. Protože není nikde uvedeno, jak se tam dostane proměnná $file, pravděpodobně půjde o volání metodou GET a povolené register_globals. Takto jsem zkoušel ukládat obrázek do souboru na serveru webzdarma.


Následovat by asi logicky měl příklad na vykreslení grafu jednoduché funkce (mazání pozadí je velký bílý obdélník) a jeho převod do formátu gif (toho staršího), protože gif nerozmazává grafy (gif má omezený počet barev, pro větší lze použít png). Případný další krok by mohl být sloupcový graf podle hodnot z tabulky SQL databáze.

Zkuste si prohlédnout seznam funkcí na adrese http://www.php.net/manual/en/ref.image.php.

Doporučuji funkce imageline, imagerectangle, imagefilledrectangle, imagestring, imagestringup, imageellipse, imagefilledellipse nebo imagefill. Problém je, že tyto funkce se vesměs těžko odlaďují (nemáme vhodnou podporu).

Jinou možností je vytvářet obrázky (zejména grafy) na straně klienta. Protože javascript pro toto neposkytuje vhodné funkce, musíme vytvořit java applet.