Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

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

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 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. Белый контекст сравнений — только фон вокруг панелей, не дополнительное поле результата.

Собственный исходник 400×320. Старая надпись PNG8 означает здесь 8 бит на компоненту RGB, не индексированный PNG.
Собственный исходник 400×320. Старая надпись PNG8 означает здесь 8 бит на компоненту RGB, не индексированный PNG.
Первый результат: поле 12 пикселей с каждой боковой стороны и 8 сверху/снизу, полный растр 424×336
Первый результат: поле 12 пикселей с каждой боковой стороны и 8 сверху/снизу, полный растр 424×336

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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.