PHP: полный мануал с примерами, функциями и ООП
Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Дерево руководства
Глава 354 · После палитр и таблиц
Imagick: поля, декоративная рамка и рельеф края
Полный растр для карточки или памятки, без обрезки и изменения масштаба.
Сохранить оформление в самом PNG
Скачиваемая карточка товара, отправляемое изображение или иллюстрация в памятке должны нести поля и рамку в самом PNG: получатель увидит оформление независимо от страницы сайта. Если рамка нужна только вокруг картинки на веб-странице, часто достаточно CSS; менять файл ради этого не обязательно. Здесь готовим переносимый растр и сохраняем исходную маркировку без изменения масштаба.
W и H — ширина и высота исходного изображения; w и h — толщина поля с каждой стороны по горизонтали и вертикали. i и o — внутренний и внешний скос frame. Все эти размеры заданы в пикселях, не в процентах. u и v — координаты исходного пикселя: отсчёт от нуля, u направо, v вниз. Поля border/frame переводят его в (u+w,v+h); размер становится (W+2w)×(H+2h). Скосы входят в w/h и дополнительно размер не увеличивают. True/false — логические значения; у raise они выбирают выпуклый/вдавленный вариант, а возвращаемое true отдельно сообщает об успехе. Цвет RGB состоит из R/G/B; #dde7ed — строка шестнадцатеричного RGB, пары dd/e7/ed соответствуют 221/231/237 в диапазоне 0..255. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.


Border: новый холст → однотонные поля → исходник со смещением (w,h). Frame: тот же рост → внутри полей светлые и тёмные полосы скосов → непрозрачный исходник в центре. Raise: прежний холст → изменить светлоту существующей краевой полосы → внутренние пиксели оставить. Последний эффект не использует соседние детали как карту высот и не строит трёхмерный объект.

Самая маленькая запись
В $image уже загружена независимая копия исходника. Первый аргумент в кавычках — строка цвета; 12 и 8 — int-поля с каждой стороны, поэтому полный результат 424×336. Все три аргумента обязательны. $ начинает имя переменной; -> вызывает метод объекта, скобки содержат аргументы, запятые разделяют их, ; завершает команду. Кавычки принадлежат PHP-строке и не становятся частью имени цвета.
$image->borderImage('#dde7ed', 12, 8);$image = clone $source; создаёт отдельный объект, простое присваивание его не копирует. Метод меняет этот объект и возвращает bool, поэтому нельзя присваивать возвращённое true обратно вместо изображения. Полный код проверяет if (!...), где ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку, clear освобождает ресурсы после записи. Подготовка: объекты и методы, clone, исключения.
Распакуйте весь ZIP: example.php, frame-fixture.php, source.png.b64. Начало <?php включает PHP; declare(strict_types=1) задаёт строгие типы вызовов. Require подключает показанный помощник из __DIR__, папки программы. LoadFrameSource проверяет Base64 и SHA256, восстанавливает точный source.png и возвращает Imagick. SaveFrameComparison размещает полные панели рядом, сохраняет PNG и печатает имя. Просмотрщик открывает изображение; stdout показывает только фиксированное имя файла.
<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->borderImage('#dde7ed', 12, 8)) {
throw new RuntimeException('Не удалось применить borderImage');
}
saveFrameComparison([$source, $image], 'frames-first.png');
$source->clear();
$image->clear();
Результат: Исходник 400×320 слева и полный border 424×336 справа. Цветная полоса RGB(221,231,237) добавлена снаружи; центральные 400×320 пикселей совпадают с исходником. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 824×336. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-first.png
Полный переносимый помощник frame-fixture.php
<?php
declare(strict_types=1);
function loadFrameSource(): Imagick
{
$encoded = file_get_contents(__DIR__ . '/source.png.b64');
if ($encoded === false) {
throw new RuntimeException('Не найден source.png.b64: распакуйте весь архив');
}
$bytes = base64_decode($encoded, true);
if ($bytes === false || hash('sha256', $bytes) !== '453b22e19273f2fdd54ec6a7f0cd9e96a7b08c70cc4cc854838d1428fea207c6') {
throw new RuntimeException('Повреждён исходный PNG');
}
$path = __DIR__ . '/source.png';
if (file_put_contents($path, $bytes) !== strlen($bytes)) {
throw new RuntimeException('Не удалось восстановить source.png');
}
return new Imagick($path);
}
function saveFrameComparison(array $panels, string $filename): void
{
if ($panels === []) {
throw new InvalidArgumentException('Нужна хотя бы одна панель');
}
$width = 0;
$height = 0;
foreach ($panels as $panel) {
if (!$panel instanceof Imagick) {
throw new InvalidArgumentException('Панель должна быть объектом Imagick');
}
$width += $panel->getImageWidth();
$height = max($height, $panel->getImageHeight());
}
$output = new Imagick();
$output->newImage($width, $height, 'white');
$output->setImageFormat('png');
$left = 0;
foreach ($panels as $panel) {
$top = intdiv($height - $panel->getImageHeight(), 2);
if (!$output->compositeImage($panel, Imagick::COMPOSITE_OVER, $left, $top)) {
throw new RuntimeException('Не удалось собрать полное сравнение');
}
$left += $panel->getImageWidth();
}
$output->setImageDepth(8);
$output->setOption('png:color-type', '2');
if (!$output->writeImage(__DIR__ . '/' . $filename)) {
throw new RuntimeException('Не удалось записать результат');
}
$output->clear();
echo $filename, "\n";
}
Function объявляет функцию; Imagick после двоеточия — тип результата загрузки, void означает отсутствие возвращаемого значения у сохранения. Массив $panels содержит объекты, foreach перебирает их; += накапливает ширину, max выбирает наибольшую высоту. Intdiv делит нацело и вычисляет вертикальный отступ для центрирования. Затем $left сдвигает следующую панель на фактическую ширину предыдущей. Это компоновка сравнения без resize и без crop результатов. Белые области над более низкой панелью — контекст просмотра, а не часть её рамки. Основы: массивы, циклы, чтение и запись.
В своём проекте сохраняют сам обработанный объект методом writeImage, когда нужна отдельная карточка. Примеры намеренно сохраняют сравнение, чтобы проверить исходник и весь результат рядом; правый растр в нём уже имеет окончательные размеры и оформление. Сохранение использует PNG с 8 битами на каждую RGB-компоненту, color-type 2; это не обещание индексированного формата или определённого размера файла.
Разделить рост холста и изменение края
При border(12,8) к 400×320 добавляются 24 столбца и 16 строк: 424×336. Пиксель исходника (u,v) оказывается в (u+12,v+8). При frame(16,16,4,4) результат 432×352; два скоса по 4 занимают часть каждого поля 16, оставляя плоскую полосу 8. Нельзя ещё раз прибавить эти скосы к ширине результата, если исходные 16 уже обозначают полное поле.
Для raise(8,8,0,0,true) весь растр остаётся 400×320. Край изменён, прямоугольник x=8..391, y=8..311 совпадает с исходником. В альтернативе false меняются направления светлого/тёмного; это входной bool. Возвращаемое true означает успешное выполнение и не сообщает, что выбран выпуклый вариант.
Перед следующей полной программой: переменные $framed и $raised — отдельные clone исходника. Цвет в кавычках задаёт RGB, числа — пиксели, true — логическое значение. Три маленьких вызова ниже показывают сами операции; помощник только собирает их готовые результаты в естественных размерах.
$image->borderImage('#dde7ed', 12, 8);
$framed->frameImage('#78909c', 16, 16, 4, 4);
$raised->raiseImage(8, 8, 0, 0, true);<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->borderImage('#dde7ed', 12, 8)) {
throw new RuntimeException('Не удалось применить borderImage');
}
$framed = clone $source;
if (!$framed->frameImage('#78909c', 16, 16, 4, 4)) {
throw new RuntimeException('Не удалось применить frameImage');
}
$raised = clone $source;
if (!$raised->raiseImage(8, 8, 0, 0, true)) {
throw new RuntimeException('Не удалось применить raiseImage');
}
saveFrameComparison([$source, $image, $framed, $raised], 'frames-controls.png');
$source->clear();
$image->clear();
$framed->clear();
$raised->clear();
Результат: Исходник, border 424×336, frame 432×352, затем raise 400×320. Все панели целиком на общем холсте 1656×352; исходные масштабы одинаковы. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 1656×352. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-controls.png
Разобрать размеры, цвета и ограничения
W и H — ширина и высота исходного изображения; w и h — толщина поля с каждой стороны по горизонтали и вертикали. i и o — внутренний и внешний скос frame. Все эти размеры заданы в пикселях, не в процентах. u и v — координаты исходного пикселя: отсчёт от нуля, u направо, v вниз. Поля border/frame переводят его в (u+w,v+h); размер становится (W+2w)×(H+2h). Скосы входят в w/h и дополнительно размер не увеличивают. True/false — логические значения; у raise они выбирают выпуклый/вдавленный вариант, а возвращаемое true отдельно сообщает об успехе. Цвет RGB состоит из R/G/B; #dde7ed — строка шестнадцатеричного RGB, пары dd/e7/ed соответствуют 221/231/237 в диапазоне 0..255. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.
| Требование | Операция | Граница |
|---|---|---|
| Добавить однотонное пространство снаружи | borderImage | Размер растёт с каждой стороны; это не внутренняя обводка и не обводка силуэта. |
| Нарисовать скосы в добавленных полях | frameImage | Скосы входят в толщину поля; это не фактурная картинка рамки. |
| Изменить внешний край прежнего растра | raiseImage | Размер тот же; x/y не выбирают ROI в проверенном Core. |
Все параметры этих трёх методов обязательны, необязательных channel/compose в них нет. Border и frame принимают строку или ImagickPixel с PECL 2.1.0. У frame inner/outer неотрицательны и в сумме не превышают ни w, ни h; равенство допустимо. Для raise нужно строго W > 2w и H > 2h. Эти правила различаются: допустимый размер скоса frame нельзя механически переносить на raise.
Не смешивайте четыре координатные задачи: толщина поля w/h, новое положение исходника внутри рамки, положение панели на холсте сравнения и локальная область crop. Обязательные x/y у raise в этой версии не решают ни одну задачу позиционирования. Процентные строки команды CLI также не являются int-пикселями PHP.
Собрать поля и окантовку

Поле добавляется с каждой стороны: 12 означает 24 дополнительных столбца. В первом результате вся новая область имеет RGB(221,231,237); в двойной окантовке внешний слой RGB(32,48,64), внутренний белый. Цвета, размеры и центральные пиксели подтверждены сохранёнными PNG, но alpha требует отдельного условия.
Если нужно сохранить прежний размер и положить линию поверх краёв, это другая задача: часть исходника будет закрыта либо нужна заранее зарезервированная область. Border не обещает одновременно сохранить размер, все исходные пиксели и добавить ненулевое внешнее поле. Мы сохраняем всю картинку и принимаем честный рост холста; фиксированный размер сервиса требует отдельного решения.
Разделить подложку, скос и локальный ярлык



У сохранённой frame базовый RGB(120,144,156), верхняя наружная полоса в контрольной точке (162,178,187), нижняя (51,62,67). Это вычисленные светлые/тёмные цвета плоского растра; рисунок не содержит физической глубины или автоматически распознанного материала. Фактура дерева, скруглённые углы и готовый дизайнерский PNG-шаблон требуют других входов и обработки.
Полный raise изменил 11264 пикселя существующего края и сохранил внутренний прямоугольник. Каждый локальный вариант ярлыка изменил 1584 пикселя внутри заданной области, снаружи ноль; внутренняя часть за полосой 4 пикселя совпала с исходником. Эти числа описывают наш макет, не универсальное количество изменённых пикселей любого входа.
Проверить сохранность пикселей и отказы
Восемь программ выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 Q16. Сохранены фактические PNG естественных размеров, точный stdout и пустой stderr. Во всех папках восстановлены исходные байты source.png; непрозрачные центры border/frame и белый контекст сравнения проверены по пикселям. Это доказательство конкретных примеров, не полнота всего руководства и не проверка печати/сканирования SKU.
Малый RGB/RGBA-контроль с непрозрачным цветом рамки и OVER показал: у border/frame прозрачный центр стал непрозрачным, у raise изменялась alpha краёв. Это не универсальный результат для всех цветов, пространств и настроек. Главные примеры намеренно непрозрачные; нельзя вывести из них сохранность произвольных прозрачных краёв, ICC/CMYK/HDR или последовательности кадров. Изображение с alpha проектируют и проверяют отдельно.
Положительная, но слишком малая геометрия frame(1,1,2,1), raise с шириной ровно половины малого входа и неверная строка цвета дали ImagickException. Необработанные внешние размеры и скосы не следует передавать в библиотеку. В приложении сначала ограничивают итоговую площадь и параметры, затем отдельно проверяют чтение, эффект и запись; пользователю не раскрывают внутренние пути. Код примеров использует фиксированные значения, внешняя валидация не реализована.
Выбрать оформление для своей карточки

- Нужно реальное пространство снаружи файла — border, учитывая рост с двух сторон.
- Нужны нарисованные свет и тень в добавленном поле — frame, скосы внутри общей толщины.
- Нужно изменить прежний край без роста — raise; для локального ярлыка сначала явный crop.
- Нужен только вид на сайте — часто достаточно CSS; нужен готовый шаблон или скругление — это отдельная компоновка/маска.
Упражнение: сохранить каталог 400×320 с белой подложкой 16/10 и рамкой 12/12, скосы 3/4. Решение: clone исходника; borderImage(white,16,10); frameImage(#78909c,12,12,3,4). В настоящем PHP цветовые строки заключены в кавычки, как в полной программе подложки и рамки. Проверьте полный размер 456×364 и начало исходника (28,22). Затем объясните, почему raise(4,4,72,140,true) не выберет тот же ярлык в этой версии.
Продолжение: палитры и lookup перед оформлением, координатные преобразования, контуры и условный рельеф, надёжная запись файлов. Сначала определите, должен ли измениться сам файл или только его показ на странице.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::borderImageДобавить поля вокруг иллюстрации без потери краёв
PECL imagick 2, PECL imagick 3 · imagick
Imagick::borderImage(mixed $bordercolor, int $width, int $height): boolПрактическая задача: Добавить поля вокруг иллюстрации без потери краёв. Затем: Собрать белое поле и тонкую контрастную окантовку.
W и H — ширина и высота исходного изображения; w и h — толщина поля с каждой стороны по горизонтали и вертикали. i и o — внутренний и внешний скос frame. Все эти размеры заданы в пикселях, не в процентах. u и v — координаты исходного пикселя: отсчёт от нуля, u направо, v вниз. Поля border/frame переводят его в (u+w,v+h); размер становится (W+2w)×(H+2h). Скосы входят в w/h и дополнительно размер не увеличивают. True/false — логические значения; у raise они выбирают выпуклый/вдавленный вариант, а возвращаемое true отдельно сообщает об успехе. Цвет RGB состоит из R/G/B; #dde7ed — строка шестнадцатеричного RGB, пары dd/e7/ed соответствуют 221/231/237 в диапазоне 0..255. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.

Самая маленькая запись
В $image уже загружена независимая копия исходника. Первый аргумент в кавычках — строка цвета; 12 и 8 — int-поля с каждой стороны, поэтому полный результат 424×336. Все три аргумента обязательны. $ начинает имя переменной; -> вызывает метод объекта, скобки содержат аргументы, запятые разделяют их, ; завершает команду. Кавычки принадлежат PHP-строке и не становятся частью имени цвета.
$image->borderImage('#dde7ed', 12, 8);$image = clone $source; создаёт отдельный объект, простое присваивание его не копирует. Метод меняет этот объект и возвращает bool, поэтому нельзя присваивать возвращённое true обратно вместо изображения. Полный код проверяет if (!...), где ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку, clear освобождает ресурсы после записи. Подготовка: объекты и методы, clone, исключения.
Сигнатура и каждый параметр
Imagick::borderImage(mixed $bordercolor, int $width, int $height): boolДобавляет равномерную однотонную область с каждой стороны. В текущем Core это рамка с нулевыми скосами. Непрозрачный исходник не масштабируется: все его пиксели сохраняются в центре со смещением (w,h). Это рост холста, а не линия поверх существующих краёв и не обводка силуэта товара.
| Аргумент | Обязательность, смысл и единицы |
|---|---|
| $bordercolor | Обязательный цвет: строка, например #dde7ed, либо объект ImagickPixel. Mixed в сигнатуре не означает, что любые массивы/объекты являются цветом. В нашем результате полоса имеет RGB(221,231,237). |
| $width | Обязательный int: толщина левого и правого поля в пикселях. При 12 ширина 400 становится 424, не 412. Не строка с процентом из CLI. |
| $height | Обязательный int: толщина верхнего и нижнего поля. При 8 высота 320 становится 336. В ограниченном непрозрачном контроле нулевая пара полей дала неизменное изображение; основные программы используют положительные размеры. |
Метод возвращает true при успехе и изменяет текущий объект; новый Imagick не возвращается. Channel-аргумента нет. Пустой объект и проверенные отказы библиотеки вызывают ImagickException; неверный тип или число аргументов могут дать PHP-ошибку. Пустая секция errors в XML не обещает отсутствие исключений. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.
Основные значения фиксированы и умеренны; внешняя форма параметров не реализована. Для внешних данных отдельно проверяют целые неотрицательные размеры, допустимые скосы, итоговую площадь холста и число кадров. Отрицательные int могут перейти в беззнаковые размеры библиотеки, поэтому их не следует проверять запуском больших случайных запросов. Память растёт с площадью новых полотен и числом копий; сравнительное быстродействие здесь не измеряется.
Полный официальный XML без изменения raw-контракта
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.borderimage">
<refnamediv>
<refname>Imagick::borderImage</refname>
<refpurpose>Surrounds the image with a border</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::borderImage</methodname>
<methodparam><type>mixed</type><parameter>bordercolor</parameter></methodparam>
<methodparam><type>int</type><parameter>width</parameter></methodparam>
<methodparam><type>int</type><parameter>height</parameter></methodparam>
</methodsynopsis>
<para>
Surrounds the image with a border of the color defined by the bordercolor ImagickPixel object.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>bordercolor</parameter></term>
<listitem>
<para>
ImagickPixel object or a string containing the border color
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>width</parameter></term>
<listitem>
<para>
Border width
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>height</parameter></term>
<listitem>
<para>
Border height
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>PECL imagick 2.1.0</entry>
<entry>
Now allows a string representing the color as the first parameter.
Previous versions allow only an ImagickPixel object.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::borderImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function borderImage($imagePath, $color, $width, $height) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->borderImage($color, $width, $height);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Официальные примеры оформлены функциями: new Imagick(realpath(path)) читает файл, метод меняет объект, header задаёт Content-Type и getImageBlob возвращает данные для echo. MIME должен соответствовать реально выбранному формату; один header сам JPEG не создаёт. Наши программы — локальные PNG, не проверка HTTP-выдачи. Полный исходный пример сохранён выше. Основы: функции, файлы, веб-ответ.

<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->borderImage('#dde7ed', 12, 8)) {
throw new RuntimeException('Не удалось применить borderImage');
}
saveFrameComparison([$source, $image], 'frames-border-basic.png');
$source->clear();
$image->clear();
Результат: Исходник 400×320 и полный результат 424×336. Поле 12 пикселей слева/справа, 8 сверху/снизу; исходные пиксели находятся в (12,8), без изменения масштаба. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 824×336. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-border-basic.png
Когда меняется требование
Для отправляемой карточки нужны белое поле вокруг товара и тонкая тёмная линия, чтобы карточка не сливалась с белой памяткой. Два последовательных border создают две независимые полосы.
Первый вызов делает белые поля 12/8, второй добавляет снаружи тёмные 2/2. Поэтому ширина равна 400+2×12+2×2=428, высота 320+2×8+2×2=340. Суммарное положение исходника (14,10). Никакой промежуточный resize не нужен; две полосы решают разные требования к отступу и внешней линии.
<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->borderImage('white', 12, 8)) {
throw new RuntimeException('Не удалось применить borderImage');
}
if (!$image->borderImage('#203040', 2, 2)) {
throw new RuntimeException('Не удалось применить borderImage');
}
saveFrameComparison([$source, $image], 'frames-border-double.png');
$source->clear();
$image->clear();
Результат: Исходник и полный результат 428×340: белые поля 12/8 пикселей, затем тёмная линия по 2 пикселя. Суммарный перенос исходника (14,10); его содержимое не обрезано. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 828×340. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-border-double.png
Для другого оформления: frameImage · raiseImage. Если нужно изменить внутренние контуры деталей, это отдельная задача: edge, emboss и shade. Для цветового оформления до рамки см. палитры и таблицы. Для вида только на веб-странице рассмотрите CSS, сохранив исходный файл.
Imagick::frameImageОформить превью рамкой с внутренним и внешним скосом
PECL imagick 2, PECL imagick 3 · imagick
Imagick::frameImage(mixed $matte_color, int $width, int $height, int $inner_bevel, int $outer_bevel): boolПрактическая задача: Оформить превью рамкой с внутренним и внешним скосом. Затем: Отделить фотографию белой подложкой от декоративной рамки.
W и H — ширина и высота исходного изображения; w и h — толщина поля с каждой стороны по горизонтали и вертикали. i и o — внутренний и внешний скос frame. Все эти размеры заданы в пикселях, не в процентах. u и v — координаты исходного пикселя: отсчёт от нуля, u направо, v вниз. Поля border/frame переводят его в (u+w,v+h); размер становится (W+2w)×(H+2h). Скосы входят в w/h и дополнительно размер не увеличивают. True/false — логические значения; у raise они выбирают выпуклый/вдавленный вариант, а возвращаемое true отдельно сообщает об успехе. Цвет RGB состоит из R/G/B; #dde7ed — строка шестнадцатеричного RGB, пары dd/e7/ed соответствуют 221/231/237 в диапазоне 0..255. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.

Самая маленькая запись
В $image уже загружена независимая копия исходника. Строка задаёт базовый цвет; 16/16 — полные поля; 4/4 — скосы внутри них. Все пять аргументов обязательны, без скрытого добавления скосов к размерам. $ начинает имя переменной; -> вызывает метод объекта, скобки содержат аргументы, запятые разделяют их, ; завершает команду. Кавычки принадлежат PHP-строке и не становятся частью имени цвета.
$image->frameImage('#78909c', 16, 16, 4, 4);$image = clone $source; создаёт отдельный объект, простое присваивание его не копирует. Метод меняет этот объект и возвращает bool, поэтому нельзя присваивать возвращённое true обратно вместо изображения. Полный код проверяет if (!...), где ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку, clear освобождает ресурсы после записи. Подготовка: объекты и методы, clone, исключения.
Сигнатура и каждый параметр
Imagick::frameImage(mixed $matte_color, int $width, int $height, int $inner_bevel, int $outer_bevel): boolДобавляет поле, в котором отдельные полосы вычисляются светлее и темнее базового цвета. Так получается нарисованный скос, а не настоящая трёхмерная рамка, текстура дерева или готовый внешний PNG-шаблон. Обычный метод в IM7 использует композицию OVER; это важно для прозрачного входа.
| Аргумент | Обязательность, смысл и единицы |
|---|---|
| $matte_color | Обязательный цвет поля: ImagickPixel или строка. Здесь #78909c, то есть RGB(120,144,156). Цветные светлые/тёмные полосы вычисляются из него; это не общая alpha-прозрачность картинки. |
| $width | Обязательный int: всё горизонтальное поле с каждой стороны, включая скосы. При 16 ширина 400 становится 432. |
| $height | Обязательный int: всё вертикальное поле, включая скосы. При 16 высота 320 становится 352. |
| $inner_bevel | Обязательный int: ширина внутреннего скоса, обращённого к изображению. В примере 4 пикселя. Он размещается внутри поля, не прибавляется к нему автоматически. |
| $outer_bevel | Обязательный int: ширина внешнего скоса. Здесь 4. Оба скоса должны быть неотрицательными; точный Core требует w >= inner+outer и h >= inner+outer, равенство допустимо. Полоса базового цвета занимает оставшееся место. |
Метод возвращает true при успехе и изменяет текущий объект; новый Imagick не возвращается. Channel-аргумента нет. Пустой объект и проверенные отказы библиотеки вызывают ImagickException; неверный тип или число аргументов могут дать PHP-ошибку. Пустая секция errors в XML не обещает отсутствие исключений. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.
Официальный пример сам выполняет width = width + innerBevel + outerBevel и то же для height, прежде чем вызвать метод. Так его автор сохраняет желаемую плоскую полосу дополнительно к скосам. Wrapper этого сложения не делает: в наших вызовах 16 уже включает оба скоса. Цвет внутренней подложки при OVER может зависеть от border_color изображения, а не только от matte_color; поэтому произвольный RGBA нельзя считать неизменным центром по непрозрачному опыту.
Основные значения фиксированы и умеренны; внешняя форма параметров не реализована. Для внешних данных отдельно проверяют целые неотрицательные размеры, допустимые скосы, итоговую площадь холста и число кадров. Отрицательные int могут перейти в беззнаковые размеры библиотеки, поэтому их не следует проверять запуском больших случайных запросов. Память растёт с площадью новых полотен и числом копий; сравнительное быстродействие здесь не измеряется.
Полный официальный XML без изменения raw-контракта
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.frameimage">
<refnamediv>
<refname>Imagick::frameImage</refname>
<refpurpose>Adds a simulated three-dimensional border</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::frameImage</methodname>
<methodparam><type>mixed</type><parameter>matte_color</parameter></methodparam>
<methodparam><type>int</type><parameter>width</parameter></methodparam>
<methodparam><type>int</type><parameter>height</parameter></methodparam>
<methodparam><type>int</type><parameter>inner_bevel</parameter></methodparam>
<methodparam><type>int</type><parameter>outer_bevel</parameter></methodparam>
</methodsynopsis>
<para>
Adds a simulated three-dimensional border around the image.
The width and height specify the border width of the vertical
and horizontal sides of the frame. The inner and outer
bevels indicate the width of the inner and outer shadows of
the frame.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>matte_color</parameter></term>
<listitem>
<para>
ImagickPixel object or a string representing the matte color
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>width</parameter></term>
<listitem>
<para>
The width of the border
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>height</parameter></term>
<listitem>
<para>
The height of the border
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>inner_bevel</parameter></term>
<listitem>
<para>
The inner bevel width
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>outer_bevel</parameter></term>
<listitem>
<para>
The outer bevel width
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
&imagick.imagick.throws;
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>PECL imagick 2.1.0</entry>
<entry>
Now allows a string representing the color as the first parameter.
Previous versions allow only an ImagickPixel object.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::frameImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function frameImage($imagePath, $color, $width, $height, $innerBevel, $outerBevel) {
$imagick = new \Imagick(realpath($imagePath));
$width = $width + $innerBevel + $outerBevel;
$height = $height + $innerBevel + $outerBevel;
$imagick->frameimage(
$color,
$width,
$height,
$innerBevel,
$outerBevel
);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Официальные примеры оформлены функциями: new Imagick(realpath(path)) читает файл, метод меняет объект, header задаёт Content-Type и getImageBlob возвращает данные для echo. MIME должен соответствовать реально выбранному формату; один header сам JPEG не создаёт. Наши программы — локальные PNG, не проверка HTTP-выдачи. Полный исходный пример сохранён выше. Основы: функции, файлы, веб-ответ.

<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->frameImage('#78909c', 16, 16, 4, 4)) {
throw new RuntimeException('Не удалось применить frameImage');
}
saveFrameComparison([$source, $image], 'frames-frame-basic.png');
$source->clear();
$image->clear();
Результат: Исходник и полный результат 432×352. Рамка по 16 пикселей с каждой стороны, оба скоса по 4 входят в эти поля. Центр исходника находится в (16,16). Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 832×352. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-frame-basic.png
Когда меняется требование
В скачиваемом превью или иллюстрации памятки изображение не должно прилегать прямо к скосу. Сначала добавим белую подложку border(16,10), затем frame(12,12,3,4). Это отдельные части оформления.
Border создаёт белую подложку: 400×320 → 432×340. Затем frame с полями 12/12 и скосами 3/4 даёт 456×364. Начало исходника смещается на (16+12,10+12)=(28,22). Подложка отделяет рисунок от скоса; это не новый параметр padding у frame и не команда перемещения всего изображения.

<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->borderImage('white', 16, 10)) {
throw new RuntimeException('Не удалось применить borderImage');
}
if (!$image->frameImage('#78909c', 12, 12, 3, 4)) {
throw new RuntimeException('Не удалось применить frameImage');
}
saveFrameComparison([$source, $image], 'frames-frame-mat.png');
$source->clear();
$image->clear();
Результат: Исходник и полный результат 456×364. Промежуточное полотно 432×340, финальное 456×364; исходник находится в (28,22). Белая подложка и цветная рамка различимы, все пиксели исходника сохранены. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 856×364. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-frame-mat.png
Для другого оформления: borderImage · raiseImage. Если нужно изменить внутренние контуры деталей, это отдельная задача: edge, emboss и shade. Для цветового оформления до рамки см. палитры и таблицы. Для вида только на веб-странице рассмотрите CSS, сохранив исходный файл.
Imagick::raiseImageСравнить выпуклый и вдавленный внешний край растра
PECL imagick 2, PECL imagick 3 · imagick
Imagick::raiseImage(int $width, int $height, int $x, int $y, bool $raise): boolПрактическая задача: Сравнить выпуклый и вдавленный внешний край растра. Затем: Оформить только ярлык, сохранив остальной макет.
W и H — ширина и высота исходного изображения; w и h — толщина поля с каждой стороны по горизонтали и вертикали. i и o — внутренний и внешний скос frame. Все эти размеры заданы в пикселях, не в процентах. u и v — координаты исходного пикселя: отсчёт от нуля, u направо, v вниз. Поля border/frame переводят его в (u+w,v+h); размер становится (W+2w)×(H+2h). Скосы входят в w/h и дополнительно размер не увеличивают. True/false — логические значения; у raise они выбирают выпуклый/вдавленный вариант, а возвращаемое true отдельно сообщает об успехе. Цвет RGB состоит из R/G/B; #dde7ed — строка шестнадцатеричного RGB, пары dd/e7/ed соответствуют 221/231/237 в диапазоне 0..255. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.

Самая маленькая запись
В $image уже загружена независимая копия исходника. 8/8 — существующая краевая полоса, 0/0 — обязательные x/y, игнорируемые этим Core, true — выпуклый вариант. Размер остаётся 400×320, все пять аргументов обязательны. $ начинает имя переменной; -> вызывает метод объекта, скобки содержат аргументы, запятые разделяют их, ; завершает команду. Кавычки принадлежат PHP-строке и не становятся частью имени цвета.
$image->raiseImage(8, 8, 0, 0, true);$image = clone $source; создаёт отдельный объект, простое присваивание его не копирует. Метод меняет этот объект и возвращает bool, поэтому нельзя присваивать возвращённое true обратно вместо изображения. Полный код проверяет if (!...), где ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку, clear освобождает ресурсы после записи. Подготовка: объекты и методы, clone, исключения.
Сигнатура и каждый параметр
Imagick::raiseImage(int $width, int $height, int $x, int $y, bool $raise): boolИзменяет уже существующую внешнюю полосу растра: смешивает компоненты её пикселей с белым/чёрным в заданных зонах. True/false меняют распределение светлого и тёмного. Новые пиксели холста не добавляются, внутреннее изображение не масштабируется. Это эффект края прямоугольника, а не распознавание формы предмета, букв или интерактивная HTML-кнопка.
| Аргумент | Обязательность, смысл и единицы |
|---|---|
| $width | Обязательный int: ширина изменяемых боковых полос в пикселях. В полном примере 8. Нужно строго 2×width < W; равенство уже недопустимо. |
| $height | Обязательный int: высота верхней/нижней полосы. Нужно строго 2×height < H. Для локального ярлыка 156×50 выбраны поля 4×4. |
| $x | Обязательный int. PHP и Wand передают его дальше, но точный Core 7.1.1-46 в RaiseImage это поле не читает. Здесь 0. Не используйте его как выбор ROI или смещение эффекта. |
| $y | Обязательный int с той же особенностью: в этой реализации не выбирает вертикальную область. Для нужного ярлыка требуется явный crop → raise → composite. |
| $raise | Обязательный bool: true даёт выпуклое, false — вдавленное оформление. Это входной выбор, независимый от bool true, возвращаемого методом при успешной обработке. |
Метод возвращает true при успехе и изменяет текущий объект; новый Imagick не возвращается. Channel-аргумента нет. Пустой объект и проверенные отказы библиотеки вызывают ImagickException; неверный тип или число аргументов могут дать PHP-ошибку. Пустая секция errors в XML не обещает отсутствие исключений. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.
В полном официальном примере есть вопросительный комментарий «x and y do nothing?». Для сохранённой версии ответ подтверждён кодом и опытом: Core эти поля не использует, вызовы с (0,0) и (5,3) на малом входе дали одинаковые RGBA-пиксели. Не переносите это как объяснение любого будущего binding без проверки. Цикл обновляемых каналов может затронуть alpha: отдельный RGBA-контроль её изменил.
Основные значения фиксированы и умеренны; внешняя форма параметров не реализована. Для внешних данных отдельно проверяют целые неотрицательные размеры, допустимые скосы, итоговую площадь холста и число кадров. Отрицательные int могут перейти в беззнаковые размеры библиотеки, поэтому их не следует проверять запуском больших случайных запросов. Память растёт с площадью новых полотен и числом копий; сравнительное быстродействие здесь не измеряется.
Полный официальный XML без изменения raw-контракта
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.raiseimage">
<refnamediv>
<refname>Imagick::raiseImage</refname>
<refpurpose>Creates a simulated 3d button-like effect</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::raiseImage</methodname>
<methodparam><type>int</type><parameter>width</parameter></methodparam>
<methodparam><type>int</type><parameter>height</parameter></methodparam>
<methodparam><type>int</type><parameter>x</parameter></methodparam>
<methodparam><type>int</type><parameter>y</parameter></methodparam>
<methodparam><type>bool</type><parameter>raise</parameter></methodparam>
</methodsynopsis>
<para>
Creates a simulated three-dimensional button-like effect
by lightening and darkening the edges of the image.
Members width and height of raise_info define the width
of the vertical and horizontal edge of the effect.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>width</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>height</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>x</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>y</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>raise</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::raiseImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function raiseImage($imagePath, $width, $height, $x, $y, $raise) {
$imagick = new \Imagick(realpath($imagePath));
//x and y do nothing?
$imagick->raiseImage($width, $height, $x, $y, $raise);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Официальные примеры оформлены функциями: new Imagick(realpath(path)) читает файл, метод меняет объект, header задаёт Content-Type и getImageBlob возвращает данные для echo. MIME должен соответствовать реально выбранному формату; один header сам JPEG не создаёт. Наши программы — локальные PNG, не проверка HTTP-выдачи. Полный исходный пример сохранён выше. Основы: функции, файлы, веб-ответ.

<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
if (!$image->raiseImage(8, 8, 0, 0, true)) {
throw new RuntimeException('Не удалось применить raiseImage');
}
$lowered = clone $source;
if (!$lowered->raiseImage(8, 8, 0, 0, false)) {
throw new RuntimeException('Не удалось применить raiseImage');
}
saveFrameComparison([$source, $image, $lowered], 'frames-raise-basic.png');
$source->clear();
$image->clear();
$lowered->clear();
Результат: Исходник, raise=true, raise=false. Все панели 400×320; меняется существующая внешняя полоса толщиной 8 пикселей. Это статическое оформление, не интерактивная кнопка или реальная 3D-модель. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 1200×320. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-raise-basic.png
Когда меняется требование
Нужен выпуклый или вдавленный ярлык MUG, а не изменение всего внешнего края каталога. x/y у raise не выбирают область: вырежем известный прямоугольник 156×50 в (72,140), обработаем его край 4 пикселя и вернём.
CropImage(width,height,x,y) вырезает известный ярлык, setImagePage(0,0,0,0) убирает виртуальное смещение. Копия $lowerLabel создаётся до raise, поэтому обе версии исходят из одинаковых пикселей. После оформления compositeImage(...,COMPOSITE_OVER,72,140) возвращает непрозрачную вырезку на свою копию макета. :: читает именованную константу класса, || означает «или» при проверке двух вставок. Вне ROI сохраняются исходные значения пикселей; это не обещание одинаковых байтов целого PNG.
<?php
declare(strict_types=1);
require __DIR__ . '/frame-fixture.php';
$source = loadFrameSource();
$image = clone $source;
$label = clone $source;
$label->cropImage(156, 50, 72, 140);
$label->setImagePage(0, 0, 0, 0);
$lowerLabel = clone $label;
if (!$label->raiseImage(4, 4, 0, 0, true)) {
throw new RuntimeException('Не удалось применить raiseImage');
}
if (!$lowerLabel->raiseImage(4, 4, 0, 0, false)) {
throw new RuntimeException('Не удалось применить raiseImage');
}
$lowered = clone $source;
if (!$image->compositeImage($label, Imagick::COMPOSITE_OVER, 72, 140) || !$lowered->compositeImage($lowerLabel, Imagick::COMPOSITE_OVER, 72, 140)) {
throw new RuntimeException('Не удалось вернуть оформленный ярлык');
}
$label->clear();
$lowerLabel->clear();
saveFrameComparison([$source, $image, $lowered], 'frames-raise-label.png');
$source->clear();
$image->clear();
$lowered->clear();
Результат: Исходник, выпуклый и вдавленный ярлык. Вне прямоугольника исходные пиксели точны; внутренняя часть ярлыка за краевой полосой тоже сохранена. Изменение относится к известному прямоугольнику, а не к распознанным буквам или силуэту товара. Архив содержит example.php, frame-fixture.php и source.png.b64. Распакуйте рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверяет SHA256, восстанавливает точный source.png без шрифтов/сети и сохраняет сравнение. Откройте PNG просмотрщиком; stdout содержит его фиксированное имя. Панели слева направо, каждая целиком в исходном масштабе, вертикально центрированы на белом контексте. Размер сравнения 1200×320. Белый контекст сравнения не является дополнительной частью рамки; надписи входного растра не пересчитываются.
Ожидаемый вывод
frames-raise-label.png
Для другого оформления: borderImage · frameImage. Если нужно изменить внутренние контуры деталей, это отдельная задача: edge, emboss и shade. Для цветового оформления до рамки см. палитры и таблицы. Для вида только на веб-странице рассмотрите CSS, сохранив исходный файл.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


