Работа с изображения

Класът Nette\Utils\Image опростява манипулирането на изображения, като например преоразмеряване, изрязване, изостряне, рисуване или комбиниране на няколко изображения.

PHP разполага с богат набор от функции за манипулиране на изображения. Но API-то им не е много удобно. Това не би бил Nette Framework, ако не предлагаше секси API.

Инсталация:

composer require nette/utils

Всички примери предполагат създаден псевдоним:

use Nette\Utils\Image;
use Nette\Utils\ImageColor;
use Nette\Utils\ImageType;

Създаване на изображение

Създаваме ново true color изображение, например с размери 100×200:

$image = Image::fromBlank(100, 200);

По желание може да се определи цвят на фона (по подразбиране е черен):

$image = Image::fromBlank(100, 200, ImageColor::rgb(125, 0, 0));

Или зареждаме изображение от файл:

$image = Image::fromFile('nette.jpg');

Запазване на изображение

Изображението може да бъде запазено във файл:

$image->save('resampled.jpg');

Можем да определим качеството на компресия в диапазона 0..100 за JPEG (по подразбиране 85), WEBP (по подразбиране 80) и AVIF (по подразбиране 30) и 0..9 за PNG (по подразбиране 9):

$image->save('resampled.jpg', 80); // JPEG, качество 80%

Ако форматът не е ясен от разширението на файла, може да се определи с константа:

$image->save('resampled.tmp', null, ImageType::JPEG);

Изображението може да бъде записано в променлива вместо на диск:

$data = $image->toString(ImageType::JPEG, 80); // JPEG, качество 80%

или да се изпрати директно в браузъра със съответния HTTP хедър Content-Type:

// изпраща хедър Content-Type: image/png
$image->send(ImageType::PNG);

Формати

Поддържаните формати са JPEG, PNG, GIF, WebP, AVIF и BMP, но те трябва да бъдат поддържани и от вашата версия на PHP, което можете да проверите с функцията isTypeSupported(). Анимациите не се поддържат.

Форматът се представя от константите ImageType::JPEG, ImageType::PNG, ImageType::GIF, ImageType::WEBP, ImageType::AVIF и ImageType::BMP.

$supported = Image::isTypeSupported(ImageType::JPEG);

Трябва ли да откриете формата на изображението при зареждане? Методът го връща във втория параметър:

$image = Image::fromFile('nette.jpg', $type);

Самото откриване без зареждане на изображението се извършва от Image::detectTypeFromFile().

Преоразмеряване

Честа операция е промяната на размерите на изображението. Текущите размери се връщат от методите getWidth() и getHeight().

За промяна се използва методът resize(). Пример за пропорционално преоразмеряване, така че да не надвишава размери 500×300 пиксела (или ширината ще бъде точно 500 px, или височината ще бъде точно 300 px, единият от размерите се изчислява така, че да се запази съотношението на страните):

$image->resize(500, 300);

Възможно е да се посочи само един размер, а другият ще бъде изчислен:

$image->resize(500, null); // ширина 500px, височината се изчислява

$image->resize(null, 300); // ширината се изчислява, височина 300px

Всеки размер може да бъде посочен и в проценти:

$image->resize('75%', 300); // 75 % × 300px

Поведението на resize може да се повлияе от следните флагове. Всички, освен Image::Stretch, запазват съотношението на страните.

Флаг Описание
Image::OrSmaller (по подразбиране) крайните размери ще бъдат по-малки или равни на исканите размери
Image::OrBigger запълва (и евентуално надхвърля в един размер) целевата площ
Image::Cover запълва целевата площ и изрязва това, което надхвърля
Image::ShrinkOnly само намаляване (предотвратява разтягането на малко изображение)
Image::Stretch не запазва съотношението на страните

Флаговете се посочват като трети аргумент на функцията:

$image->resize(500, 300, Image::OrBigger);

Флаговете могат да се комбинират:

$image->resize(500, 300, Image::ShrinkOnly | Image::Stretch);

Изображенията могат да бъдат обърнати вертикално или хоризонтално, като един от размерите (или и двата) се посочи като отрицателно число:

$flipped = $image->resize(null, '-100%'); // обръщане вертикално

$flipped = $image->resize('-100%', '-100%'); // завъртане на 180°

$flipped = $image->resize(-125, 500); // преоразмеряване и обръщане хоризонтално

След намаляване на размера на изображението е възможно да се подобри външният му вид чрез леко изостряне:

$image->sharpen();

Изрязване

За изрязване се използва методът crop():

$image->crop($left, $top, $width, $height);

Подобно на resize(), всички стойности могат да бъдат посочени в проценти. Процентите за $left и $top се изчисляват от оставащото място, подобно на CSS свойството background-position:

$image->crop('100%', '50%', '80%', '80%');

Изображението може също да бъде изрязано автоматично, например изрязване на черни рамки:

$image->cropAuto(IMG_CROP_BLACK);

Методът cropAuto() е обектен заместител на функцията imagecropauto(), в нейната документация ще намерите повече информация.

Цветове

Методът ImageColor::rgb() ви позволява да дефинирате цвят чрез стойностите на червено, зелено и синьо (RGB). По желание можете да посочите и стойност на прозрачност в диапазона от 0 (напълно прозрачно) до 1 (напълно непрозрачно), т.е. същото като в CSS.

$color = ImageColor::rgb(255, 0, 0); // Червено
$transparentBlue = ImageColor::rgb(0, 0, 255, 0.5); // Полупрозрачно синьо

Методът ImageColor::hex() позволява да дефинирате цвят чрез шестнадесетичен формат, подобно на CSS. Поддържа форматите #rgb, #rrggbb, #rgba и #rrggbbaa:

$color = ImageColor::hex("#F00"); // Червено
$transparentGreen = ImageColor::hex("#00FF0080"); // Полупрозрачно зелено

Цветовете могат да се използват в други методи, като ellipse(), fill() и т.н.

Рисуване и редакции

Можеш да рисуваш, можеш да пишеш, но не късай листата. На ваше разположение са всички функции на PHP за работа с изображения, вижте Преглед на методите, но в обектна обвивка:

$image->filledEllipse($centerX, $centerY, $width, $height, ImageColor::rgb(255, 0, 0));

Тъй като PHP функциите за рисуване на правоъгълници са непрактични поради определянето на координати, класът Image предлага техни заместители под формата на функциите rectangleWH() и filledRectangleWH().

Комбиниране на няколко изображения

В изображението лесно може да се вмъкне друго изображение:

$logo = Image::fromFile('logo.png');
$blank = Image::fromBlank(320, 240, ImageColor::rgb(52, 132, 210));

// координатите могат да бъдат посочени отново в проценти
$blank->place($logo, '80%', '80%'); // вмъкваме близо до долния десен ъгъл

При вмъкването се спазва алфа каналът, освен това можем да повлияем на прозрачността на вмъкваното изображение (създаваме т.нар. воден знак):

$blank->place($image, '80%', '80%', 25); // прозрачността е 25 %

Такова API е наистина удоволствие да се използва!

Преглед на методите

static fromBlank (int $width, int $height, ?ImageColor $color=null)Image

Създава ново true color изображение с дадените размери. Цветът по подразбиране е черен.

static fromFile (string $file, int &$detectedFormat=null)Image

Зарежда изображение от файл и връща неговия тип в $detectedFormat.

static fromString (string $s, int &$detectedFormat=null)Image

Зарежда изображение от низ и връща неговия тип в $detectedFormat.

static rgb (int $red, int $green, int $blue, int $transparency=0)array

Тази функция е заменена от класа ImageColor, вижте цветове.

static typeToExtension (int $type)string

Връща разширението на файла за дадения тип.

static typeToMimeType (int $type)string

Връща mime типа за дадения тип.

static extensionToType (string $extension)int

Връща тип на изображението според разширението на файла.

static detectTypeFromFile (string $file, int &$width=null, int &$height=null)?int

Връща тип на изображението и в параметрите $width и $height също неговите размери.

static detectTypeFromString (string $s, int &$width=null, int &$height=null)?int

Връща тип на изображението от низ и в параметрите $width и $height също неговите размери.

static isTypeSupported (int $type)bool

Проверява дали даденият тип на изображението е поддържан.

static getSupportedTypes(): array

Връща масив от поддържаните типове на изображения.

static calculateTextBox (string $text, string $fontFile, float $size, float $angle=0, array $options=[])array

Изчислява размерите на правоъгълника, който обхваща текста с определен шрифт и размер. Връща асоциативен масив, съдържащ ключовете left, top, width, height. Левият ръб може да бъде и отрицателен, ако текстът започва с ляво подрязване.

affine (array $affine, ?array $clip=null)Image

Върнете изображение, съдържащо афинно трансформирано изображение src, като използвате незадължителна област на изрязване. (повече).

affineMatrixConcat (array $m1, array $m2)array

Връща конкатенацията на две афинни трансформационни матрици, което е полезно, ако няколко трансформации трябва да се приложат едновременно към едно и също изображение. (повече)

affineMatrixGet (int $type, ?mixed $options=null)array

Връща матрична трансформационна матрица. (повече)

alphaBlending (bool $on)void

Позволява два различни режима на рисуване в truecolor изображения. В режим на смесване, алфа каналният компонент на цвета, използван във всички функции за рисуване, като setPixel(), определя до каква степен трябва да се позволи на основния цвят да прозира. В резултат на това съществуващият цвят в този момент автоматично се смесва с рисувания цвят и резултатът се запазва в изображението. Крайният пиксел е непрозрачен. В режим без смесване, рисуваният цвят се копира буквално с информацията за алфа канала и замества целевия пиксел. Режимът на смесване не е наличен при рисуване върху палетни изображения. (повече)

antialias (bool $on): void

Активирайте рисуването на изгладени линии и полигони. Не поддържа алфа канали. Работи само с truecolor изображения.

Използването на антиалиасни примитиви с прозрачен цвят на фона може да доведе до неочаквани резултати. Методът на смесване използва цвета на фона като всички останали цветове. (повече)

arc (int $centerX, int $centerY, int $width, int $height, int $startAngle, int $endAngle, ImageColor $color)void

Рисува дъга от кръг с център в дадените координати. (повече)

colorAllocate (int $red, int $green, int $blue)int

Връща идентификатор на цвят, представляващ цвета, съставен от дадените RGB компоненти. Трябва да се извика за създаване на всеки цвят, който ще се използва в изображението. (повече)

colorAllocateAlpha (int $red, int $green, int $blue, int $alpha)int

Действа по същия начин като colorAllocate() с добавяне на параметър за прозрачност $alpha. (повече)

colorAt (int $x, int $y)int

Връща индекса на цвета на пиксела на определеното място в изображението. Ако изображението е truecolor, тази функция връща RGB стойността на този пиксел като цяло число. Използвайте битово изместване и битово маскиране за достъп до отделните стойности на червения, зеления и синия компонент: (повече)

colorClosest (int $red, int $green, int $blue)int

Връща индекса на цвета в палитрата на изображението, който е „най-близък“ до зададената RGB стойност. “Разстоянието” между искания цвят и всеки цвят в палитрата се изчислява, сякаш RGB стойностите представляват точки в триизмерно пространство. (повече)

colorClosestAlpha (int $red, int $green, int $blue, int $alpha)int

Връща индекса на цвета в палитрата на изображението, който е „най-близък“ до зададената RGB стойност и ниво $alpha. (повече)

colorClosestHWB (int $red, int $green, int $blue)int

Получете индекса на цвета, който има оттенък, бяло и черно най-близо до дадения цвят. (повече)

colorDeallocate (int $color)void

Де-алокира цвят, предварително разпределен с colorAllocate() или colorAllocateAlpha(). (повече)

colorExact (int $red, int $green, int $blue)int

Връща индекса на зададения цвят в палитрата на изображението. (повече)

colorExactAlpha (int $red, int $green, int $blue, int $alpha)int

Връща индекса на зададения цвят + алфа в палитрата на изображението. (повече)

colorMatch (Image $image2)void

Приспособява цветовете на палитрата към второто изображение. (повече)

colorResolve (int $red, int $green, int $blue)int

Връща индекс на цвят за искания цвят, или точния цвят, или най-близката възможна алтернатива. (повече)

colorResolveAlpha (int $red, int $green, int $blue, int $alpha)int

Връща индекс на цвят за искания цвят, или точния цвят, или най-близката възможна алтернатива. (повече)

colorSet (int $index, int $red, int $green, int $blue)void

Задава указания индекс в палитрата на зададения цвят. (повече)

colorsForIndex (int $index)array

Получава цвета на указания индекс. (повече)

colorsTotal(): int

Връща броя на цветовете в палитрата на изображението. (повече)

colorTransparent (?int $color=null)int

Получава или задава прозрачния цвят в изображението. (повече)

convolution (array $matrix, float $div, float $offset)void

Прилага конволюционна матрица към изображението, като използва дадения коефициент и отместване. (повече)

Изисква наличието на Bundled GD extension, така че може да не работи навсякъде.

copy (Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH)void

Копира част от $src върху изображението, започвайки от координати $srcX, $srcY с ширина $srcW и височина $srcH. Дефинираната част ще бъде копирана на координати $dstX и $dstY. (повече)

copyMerge (Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH, int $opacity)void

Копира част от $src върху изображението, започвайки от координати $srcX, $srcY с ширина $srcW и височина $srcH. Дефинираната част ще бъде копирана на координати $dstX и $dstY. (повече)

copyMergeGray (Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $srcW, int $srcH, int $opacity)void

Копира част от $src върху изображението, започвайки от координати $srcX, $srcY с ширина $srcW и височина $srcH. Дефинираната част ще бъде копирана на координати $dstX и $dstY.

Тази функция е идентична с copyMerge() с изключение на това, че при сливането запазва оттенъка на източника, като преобразува целевите пиксели в сива скала преди операцията по копиране. (повече)

copyResampled (Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $dstW, int $dstH, int $srcW, int $srcH)void

Копира правоъгълна част от едно изображение върху друго изображение, гладко интерполира стойностите на пикселите, така че особено намаляването на размера на изображението все още запазва голяма яснота.

С други думи, copyResampled() взема правоъгълна област от $src с ширина $srcW и височина $srcH в позиция ($srcX, $srcY) и я поставя в правоъгълна област на изображението с ширина $dstW и височина $dstH в позиция ($dstX, $dstY).

Ако изходните и целевите координати, ширина и височина се различават, се извършва съответното разтягане или свиване на фрагмента на изображението. Координатите се отнасят до горния ляв ъгъл. Тази функция може да се използва за копиране на области в рамките на едно и също изображение, но ако областите се припокриват, резултатите няма да бъдат предвидими. (повече)

copyResized (Image $src, int $dstX, int $dstY, int $srcX, int $srcY, int $dstW, int $dstH, int $srcW, int $srcH)void

Копира правоъгълна част от едно изображение върху друго изображение. С други думи, copyResized() получава правоъгълна област от $src с ширина $srcW и височина $srcH в позиция ($srcX, $srcY) и я поставя в правоъгълна област на изображението с ширина $dstW ] и височина $dstH в позиция ($dstX, $dstY).

Ако изходните и целевите координати, ширина и височина се различават, се извършва съответното разтягане или свиване на фрагмента на изображението. Координатите се отнасят до горния ляв ъгъл. Тази функция може да се използва за копиране на области в рамките на едно и също изображение, но ако областите се припокриват, резултатите няма да бъдат предвидими. (повече)

crop (int|string $left, int|string $top, int|string $width, int|string $height)Image

Изрязва изображението до дадената правоъгълна област. Размерите могат да се задават като цели числа в пиксели или низове в проценти (например '50%').

cropAuto (int $mode=-1, float $threshold=.5, ?ImageColor $color=null)Image

Автоматично изрязва изображението според дадения $mode. (повече)

ellipse (int $centerX, int $centerY, int $width, int $height, ImageColor $color)void

Рисува елипса с център на зададените координати. (повече)

fill (int $x, int $y, ImageColor $color)void

Запълва област, започвайки от дадената координата (горе вляво е 0, 0) с дадения $color. (повече)

filledArc (int $centerX, int $centerY, int $width, int $height, int $startAngle, int $endAngle, ImageColor $color, int $style)void

Рисува частична дъга с център на зададените координати. (повече)

filledEllipse (int $centerX, int $centerY, int $width, int $height, ImageColor $color)void

Рисува елипса с център на зададените координати. (повече)

filledPolygon (array $points, ImageColor $color)void

Създава в изображението запълнен многоъгълник. (повече)

filledRectangle (int $x1, int $y1, int $x2, int $y2, ImageColor $color)void

Създава правоъгълник, запълнен с $color в изображението, започвайки от точка $x1 & $y1 и завършвайки в точка $x2 & $y2. Точка 0, 0 е горният ляв ъгъл на изображението. (повече)

filledRectangleWH (int $left, int $top, int $width, int $height, ImageColor $color)void

Създава правоъгълник, запълнен с $color в изображението, започвайки от точка $left & $top с ширина $width и височина $height. Точка 0, 0 е горният ляв ъгъл на изображението.

fillToBorder (int $x, int $y, int $border, ImageColor $color)void

Извършва запълване, чийто цвят на границата е дефиниран с $border. Началната точка на запълването е $x, $y (горе вляво е 0, 0) и областта се запълва с цвят $color. (повече)

filter (int $filtertype, int …$args)void

Прилага дадения филтър $filtertype към изображението. (повече)

flip (int $mode): void

Обръща изображението, използвайки дадения $mode. (повече)

ftText (float $size, float $angle, int $x, int $y, ImageColor $color, string $fontFile, string $text, array $options=[])array

Напишете текст в изображението. (повече)

gammaCorrect (float $inputgamma, float $outputgamma)void

Прилага гама корекция към изображението спрямо входната и изходната гама. (повече)

getClip(): array

Връща текущото изрязване, т.е. областта, извън която няма да бъдат нарисувани пиксели. (повече)

getHeight(): int

Връща височината на изображението.

getImageResource(): resource|GdImage

Връща оригиналния ресурс.

getWidth(): int

Връща ширината на изображението.

interlace (?int $interlace=null)int

Включва или изключва режима на преплитане. Ако режимът на преплитане е зададен и изображението се запазва като JPEG, то ще бъде запазено като прогресивен JPEG. (повече)

isTrueColor(): bool

Установява дали изображението е truecolor. (повече)

layerEffect (int $effect)void

Задайте флага за алфа смесване, за да използвате ефекти на слоеве. (повече)

line (int $x1, int $y1, int $x2, int $y2, ImageColor $color)void

Рисува линия между две дадени точки. (повече)

openPolygon (array $points, ImageColor $color)void

Рисува отворен многоъгълник върху изображението. За разлика от polygon(), между последната и първата точка не се рисува линия. (повече)

paletteCopy (Image $source)void

Копира палитрата от $source в изображението. (повече)

paletteToTrueColor(): void

Преобразува изображение, базирано на палитра, в пълноцветно изображение. (повече)

place (Image $image, int|string $left=0, int|string $top=0, int $opacity=100)Image

Копира $image в изображението на координати $left и $top. Координатите могат да се задават като цели числа в пиксели или низове в проценти (например '50%').

polygon (array $points, ImageColor $color)void

Създава многоъгълник в изображението. (повече)

rectangle (int $x1, int $y1, int $x2, int $y2, ImageColor $color)void

Създава правоъгълник на зададените координати. (повече)

rectangleWH (int $left, int $top, int $width, int $height, ImageColor $color)void

Създава правоъгълник на зададените координати.

resize (int|string $width, int|string $height, int $flags=Image::OrSmaller)Image

Преоразмерява изображението, повече информация. Размерите могат да се задават като цели числа в пиксели или низове в проценти (например '50%').

resolution (?int $resX=null, ?int $resY=null)mixed

Задава или връща резолюцията на изображението в DPI (точки на инч). Ако не е зададен нито един от незадължителните параметри, текущата резолюция се връща като индексиран масив. Ако е зададен само $resX, хоризонталната и вертикалната резолюция се задават на тази стойност. Ако са зададени и двата незадължителни параметъра, хоризонталната и вертикалната резолюция се задават на тези стойности.

Резолюцията се използва само като мета информация, когато изображенията се четат и записват във формати, поддържащи този вид информация (в момента PNG и JPEG). Тя не влияе на никакви операции по рисуване. Резолюцията по подразбиране на новите изображения е 96 DPI. (повече)

rotate (float $angle, int $backgroundColor)Image

Завърта изображението с дадения $angle в градуси. Центърът на въртене е центърът на изображението и завъртяното изображение може да има различни размери от оригиналното изображение. (повече)

Изисква наличието на Bundled GD extension, така че може да не работи навсякъде.

save (string $file, ?int $quality=null, ?int $type=null)void

Запазва изображението във файл.

Качеството на компресия е в диапазона 0..100 за JPEG (по подразбиране 85), WEBP (по подразбиране 80) и AVIF (по подразбиране 30) и 0..9 за PNG (по подразбиране 9). Ако типът не е ясен от разширението на файла, можете да го зададете с помощта на една от константите ImageType.

saveAlpha (bool $saveflag)void

Задава флага дали при запазване на PNG изображения да се запази пълната информация за алфа канала (за разлика от едноцветната прозрачност).

Алфа смесването трябва да бъде деактивирано (alphaBlending(false)), за да се запази алфа каналът на първо място. (повече)

scale (int $newWidth, int $newHeight=-1, int $mode=IMG_BILINEAR_FIXED)Image

Мащабира изображението, използвайки дадения интерполационен алгоритъм. (повече)

send (int $type=ImageType::JPEG, ?int $quality=null)void

Извежда изображението в браузъра.

Качеството на компресия е в диапазона 0..100 за JPEG (по подразбиране 85), WEBP (по подразбиране 80) и AVIF (по подразбиране 30) и 0..9 за PNG (по подразбиране 9).

setBrush (Image $brush)void

Задава изображението на четката, което ще се използва във всички функции за рисуване на линии (например line() и polygon()) при рисуване със специалните цветове IMG_COLOR_BRUSHED или IMG_COLOR_STYLEDBRUSHED. (повече)

setClip (int $x1, int $y1, int $x2, int $y2)void

Задава текущото изрязване, т.е. областта, извън която няма да бъдат нарисувани пиксели. (повече)

setInterpolation (int $method=IMG_BILINEAR_FIXED)void

Задава метода на интерполация, който влияе на методите rotate() и affine(). (повече)

setPixel (int $x, int $y, ImageColor $color)void

Рисува пиксел на зададената координата. (повече)

setStyle (array $style)void

Задава стила, който трябва да се използва от всички функции за рисуване на линии (например line() и polygon()) при рисуване със специалния цвят IMG_COLOR_STYLED или линии от изображения с цвят IMG_COLOR_STYLEDBRUSHED. (повече)

setThickness (int $thickness)void

Задава дебелината на линиите при рисуване на правоъгълници, многоъгълници, дъги и т.н. на $thickness пиксела. (повече)

setTile (Image $tile)void

Задава изображението на плочката, което ще се използва във всички функции за запълване на региони (например fill() и filledPolygon()), когато се запълва със специалния цвят IMG_COLOR_TILED.

Плочката е изображение, използвано за запълване на област с повтарящ се модел. Всяко изображение може да се използва като плочка и чрез задаване на прозрачен цветен индекс на изображението на плочката с colorTransparent() може да се създаде плочка, където определени части от подлежащата област ще прозират. (повече)

sharpen(): Image

Изостря изображението.

Изисква наличието на Bundled GD extension, така че може да не работи навсякъде.

toString (int $type=ImageType::JPEG, ?int $quality=null)string

Запазва изображението в низ.

Качеството на компресия е в диапазона 0..100 за JPEG (по подразбиране 85), WEBP (по подразбиране 80) и AVIF (по подразбиране 30) и 0..9 за PNG (по подразбиране 9).

trueColorToPalette (bool $dither, int $ncolors)void

Преобразува truecolor изображение в палетно. (повече)

ttfText (float $size, float $angle, int $x, int $y, ImageColor $color, string $fontFile, string $text, array $options=[])array

Извежда дадения текст в изображението. (повече)

версия: 4.0