Работа с изображения
Класът 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
Извежда дадения текст в изображението. (повече)