Edit
Lang

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!