Zpracování obrázků
Třída Nette\Utils\Image je určena pro základní manipulaci s obrázky. Zjednodušuje nejčastější úkony, jako je změna velikosti, doostření nebo odeslání do prohlížeče.
Základní manipulace s obrázky, jako je zmenšení, oříznutí nebo doostření, obnáší v PHP psaní nečitelného a nesrozumitelnému kódu. Vyjádřeno velmi diplomaticky :-) A to by nebyl Nette Framework, aby nepřišel s příjemnějším API.
Nejprve obrázek načteme ze souboru:
use Nette\Utils\Image;
$image = Image::fromFile('nette.jpg');
nebo vytvoříme obrázek nový, prázdný, s rozměry 100×200:
$image = Image::fromBlank(100, 200);
Volitelně lze určit také barvu pozadí (výchozí je černá):
$image = Image::fromBlank(100, 200, Image::rgb(125, 0, 0));
A vypíšeme jeho rozměry:
echo "Rozměry jsou $image->width × $image->height";
Změna velikosti
Ke změně velikosti se používá metoda resize
. První dva parametry určují šířku a výšku, volitelný
třetí slouží pro příznaky.
Proporcionální změna velikosti tak, aby nepřesáhl rozměry 50×30 pixelů (buď bude šířka přesně 50 px nebo výška bude přesně 30 px, druhý rozměr se dopočítá tak, aby byl zachován poměr stran):
$image->resize(50, 30);
Je možné specifikovat jen jeden rozměr a druhý se dopočítá:
$image->resize(50, NULL); // šířka 50px, výška se dopočítá
$image->resize(NULL, 30); // šířka se dopočítá, výška 30px
Kterýkoliv rozměr je možné uvést i v procentech:
$image->resize('75%', 30); // 75 % × 30px
Chování resize
lze ovlivnit následujícími příznaky:
Příznak | Popis |
---|---|
Image::FIT (výchozí) |
výsledné rozměry budou menší nebo rovny požadovaným rozměrům |
Image::FILL |
vyplní (a případně přesáhne v jednom rozměru) cílovou plochu |
Image::EXACT |
vyplní cílovou plochu a ořízne to, co přesáhne |
Image::SHRINK_ONLY |
pouze zmenšování (zabrání roztažení malého obrázku) |
Image::STRETCH |
nezachovávat poměr stran |
Příznaky se uvádějí jako třetí argument funkce:
$image->resize(50, 30, Image::STRETCH);
Příznaky lze kombinovat:
$image->resize(50, 30, Image::SHRINK_ONLY | Image::STRETCH);
Obrázky lze vertikálně nebo horizontálně překlopit tak, že jeden z rozměrů (případně oba) uvedeme jako záporné číslo:
$flipped = $image->resize(NULL, '-100%'); // flip vertical
$flipped = $image->resize('-100%', '-100%'); // rotate 180°
$flipped = $image->resize(-125, 50); // resize & flip horizontal
Úpravy
Po zmenšení obrázku je možné vylepšit jeho vzhled jemným doostřením:
$image->sharpen();
Obrázek ořízneme dle souřadnic obdélníku:
$image->crop($left, $top, $width, $height);
Zmenšený obrázek můžeme vložit do jiného (vytvoříme tzv. watermark):
$blank = Image::fromBlank(320, 240, Image::rgb(52, 132, 210));
$blank->place($image, 0, 0); // vložíme na pozici 0px, 0px
// souřadnice lze uvést opět v procentech
$blank->place($image, '80%', '75%', 25); // průhlednost je 25 %
Image zjednodušuje volání všech grafických funkcí PHP z rozšíření GD, například imagefilledrectangle, ale s využitím srozumitelnějšího objektového přístupu:
$white = Image::rgb(255, 255, 255);
$image->filledRectangle(0, 0, $width, $height, $white);
Funkce sharpen()
a rotate()
vyžadují přítomnost Bundled GD extension,
nemusí tedy fungovat všude.
Uložení obrázku
Obrázek lze uložit do souboru:
$image->save('resampled.jpg');
Volitelně lze stanovit i kvalitu a formát obrázku. (Pokud není uveden, detekuje se z přípony):
$image->save('resampled.jpg', 80, Image::JPEG); // JPEG, kvalita 80%
Alternativně lze obrázek uložit i do proměnné:
$binary = (string) $image;
nebo poslat přímo do prohlížeče s nastavením příslušné hlavičky Content-Type
:
// odešle jako image/jpeg
$image->send();
// odešle jako image/png
$image->send(Image::PNG);
Protože vykreslení obrázku tím, že dáte odkaz na prezenter, který zavolá $image->send(); nemusí být zrovna nejrychlejší, je lepší si změněný obrázek někam uložit a pak zobrazovat přímo ten uložený obrázek, bez použití $image->send(); Pro inspiraci se můžete podívat na fórum.
Takové API je skutečně radost používat!