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

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

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

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

Глава 349 · После локальной статистики и фильтров

Imagick: контуры, рельеф и условное освещение

От окна соседей и первого edge до рельефной вставки, градусных углов света и проверенной сохранности внешнего макета.

Зачем нужны контуры, рельеф и светотень

Для каталога нужен контурный просмотр товара, а для отдельного оформительского варианта — рельеф и выбранная светотень. При этом SKU и исходник должны оставаться доступными без изменений. Эти задачи отличаются от восстановления фотографии: яркость бумаги и цвет кружки не дают достоверную трёхмерную форму.

Собственный вход 400×320: каталог, шумный ярлык, защищаемая SKU, серая и цветная условные карты высот, перепад 64/192
Собственный вход 400×320: каталог, шумный ярлык, защищаемая SKU, серая и цветная условные карты высот, перепад 64/192

Уровни 0..255 на схеме — значения отображаемого PNG8, не реальные миллиметры высоты. Radius — радиус соседства в пикселях, sigma — стандартное отклонение Gaussian в пикселях; 0 у radius означает автоматический выбор. Azimuth — направление условного света, elevation — угол возвышения: оба в градусах. Gray=true выводит освещённость, false умножает на неё исходные RGB. Q означает QuantumRange, максимум внутреннего канала: в проверенной Q16-сборке 65535; углы и radius на Q не умножают. Координата x растёт вправо, y вниз.

Первый результат: edge с radius=1 пиксель; видны перепады, включая буквы и шум, а не только силуэт товара
Первый результат: edge с radius=1 пиксель; видны перепады, включая буквы и шум, а не только силуэт товара

Edge сравнивает центр с соседями: на постоянном участке разница исчезает, возле перепада возникает отклик. Emboss применяет направленные положительные/отрицательные веса и затем выравнивает распределение уровней, создавая рельефную подачу. Shade оценивает наклон по интенсивности соседей — численной яркости, полученной из цветовых компонентов, — и сопоставляет его с направлением воображаемого света. Это три разных численных правила; ни одно не распознаёт материал, истинный силуэт или геометрию кружки.

Перепады → контур; направленные веса → рельеф и Equalize; условные наклоны + свет → освещённость или освещённость × RGB
Перепады → контур; направленные веса → рельеф и Equalize; условные наклоны + свет → освещённость или освещённость × RGB

Самая маленькая запись

В $image уже находится загруженная копия. 1 — радиус в пикселях, не толщина внешнего stroke. 0 разрешил бы автоматический размер. Стрелка -> вызывает метод объекта, круглые скобки содержат аргументы, запятые их отделяют, ; завершает команду.

$image->edgeImage(1);

Чтобы сохранить оригинал, сначала $image = clone $source; создаёт независимую копию, простое присваивание объект не копирует. Метод меняет текущую картинку. В полном коде if с ! проверяет false, throw new RuntimeException прекращает отказавшую цепочку; clear освобождает native-ресурсы после сохранения. Подготовка: объекты и методы, clone, исключения.

Распакуйте весь архив: example.php — программа, relief-fixture.php — показанный ниже помощник, source.png.b64 — текстовое Base64-представление точного PNG. Require подключает файл относительно __DIR__, папки программы. LoadReliefSource возвращает Imagick: декодирует данные, проверяет SHA256 и восстанавливает source.png. SaveReliefComparison собирает панели и сохраняет RGB PNG8, затем печатает имя. Откройте этот файл просмотрщиком: stdout — имя, не содержимое картинки.

Константа Imagick::VIRTUALPIXELMETHOD_EDGE задаёт соседей за рамкой: продолжение крайних пикселей. :: без скобок читает константу класса; это не вызов метода. Правило выбрано до clone, поэтому копии его наследуют. Все основные параметры и источник фиксированы, результат можно сопоставить с оригиналом.

Получить первый контурный PNGПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->edgeImage(1)) {
    throw new RuntimeException('Не удалось применить edgeImage');
}
saveReliefComparison([$source, $image], 'relief-first.png');
$source->clear();
$image->clear();

Результат: Панели: исходник, edge с радиусом 1 пиксель. Ровные внутренние участки перепада становятся чёрными, возле скачка виден положительный отклик. Текст и шум также создают отклик; это не автоматически выделенный силуэт предмета и не векторная обводка. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 800×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-first.png
Полный переносимый помощник relief-fixture.php
<?php
declare(strict_types=1);

function loadReliefSource(): 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) !== '52ae7a9ad71be9146b3aeaa55acfebf4d295de77019f3fd9c1af790c2727ebae') {
        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 saveReliefComparison(array $panels, string $filename): void
{
    if ($panels === []) {
        throw new InvalidArgumentException('Нужна хотя бы одна панель');
    }
    $output = new Imagick();
    $output->newImage(400 * count($panels), 320, 'white');
    $output->setImageFormat('png');
    foreach ($panels as $index => $panel) {
        if (!$panel instanceof Imagick || $panel->getImageWidth() !== 400 || $panel->getImageHeight() !== 320) {
            throw new InvalidArgumentException('Панель должна быть Imagick 400 на 320 пикселей');
        }
        if (!$output->compositeImage($panel, Imagick::COMPOSITE_OVER, 400 * $index, 0)) {
            throw new RuntimeException('Не удалось собрать сравнение');
        }
    }
    $output->setImageDepth(8);
    $output->setOption('png:color-type', '2');
    if (!$output->writeImage(__DIR__ . '/' . $filename)) {
        throw new RuntimeException('Не удалось записать результат');
    }
    $output->clear();
    echo $filename, "\n";
}

Помощник объявляет function с параметрами и типом результата после двоеточия. Load возвращает Imagick, save имеет void — возвращаемого значения нет. Array $panels — список изображений, foreach перебирает объекты и индексы, count считает панели. Проверки чтения/хеша/размеров прекращают повреждённый вход; composite размещает непрозрачные панели без изменения масштаба. Это инфраструктура воспроизводимого запуска, не скрытый алгоритм фильтров. Подготовка: функции, массивы, foreach, чтение и запись файлов.

Связать вызов с соседями и новым значением пикселя

У edge с radius=1 точное ядро 3×3: центр +8, восемь соседей −1. Для центра 129 среди восьми 128 получаем 8×129−8×128=8. На ровном поле 128 получаем 0. Это локальная свёртка, а не распознавание контура; отрицательная сторона отклика ограничивается допустимым диапазоном. Radius=0 автоматически выбирает размер и не обещает всегда 3×3.

У emboss направленное Gaussian-derived ядро, а затем Equalize. Рельефная подача может менять цвет и распределение всей обрабатываемой области; нейтральный серый нужно готовить явно. У shade нормаль оценивается по интенсивностям окрестности 3×3. Для ровной непрозрачной области и gray=true в этой C-реализации освещённость равна Q×sin(elevation). Здесь sin — математический синус угла, задающий вертикальную долю направления света: при 30° около половины диапазона, при 90° максимум. Это поясняющая формула, не новый вызов PHP и не полный независимый алгоритм освещения.

До сравнительной программы: $image, $embossed, $shaded — отдельные clone из $source. Вызовы ниже показывают ядро: 1 — edge radius; 0/1 — auto radius/sigma emboss; true/135/45 — gray и два угла shade. Запятые отделяют аргументы, true — логическое значение, не строка с текстом.

$image->edgeImage(1);
$embossed->embossImage(0, 1);
$shaded->shadeImage(true, 135, 45);
Сравнить три преобразования исходного макетаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->edgeImage(1)) {
    throw new RuntimeException('Не удалось применить edgeImage');
}
$embossed = clone $source;
if (!$embossed->embossImage(0, 1)) {
    throw new RuntimeException('Не удалось применить embossImage');
}
$shaded = clone $source;
if (!$shaded->shadeImage(true, 135, 45)) {
    throw new RuntimeException('Не удалось применить shadeImage');
}
saveReliefComparison([$source, $image, $embossed, $shaded], 'relief-controls.png');
$source->clear();
$image->clear();
$embossed->clear();
$shaded->clear();

Результат: Панели: исходник, edge(1), emboss(0,1), shade(true,135,45). Постоянное поле, склон, цветная плашка и шумный ярлык показывают различие правил. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 1600×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-controls.png

Разобрать параметры до выбора эффекта

Уровни 0..255 на схеме — значения отображаемого PNG8, не реальные миллиметры высоты. Radius — радиус соседства в пикселях, sigma — стандартное отклонение Gaussian в пикселях; 0 у radius означает автоматический выбор. Azimuth — направление условного света, elevation — угол возвышения: оба в градусах. Gray=true выводит освещённость, false умножает на неё исходные RGB. Q означает QuantumRange, максимум внутреннего канала: в проверенной Q16-сборке 65535; углы и radius на Q не умножают. Координата x растёт вправо, y вниз.

ЗаписьЧто контролируетсяЧего она не означает
edgeImage(1)Радиус в пикселях, здесь 3×3 свёртка.Не внешняя рамка толщиной 1 и не векторизация.
embossImage(0,1)Автоматический радиус и sigma=1 px.Не глубина тиснения в миллиметрах и не гарантированный серый цвет.
shadeImage(true,135,45)Освещённость при двух углах в градусах.Не перемещение лампы на 45 пикселей и не реальная модель поверхности.
shadeImage(false,135,45)Тот же свет, умноженный на исходные каналы.Не неизменённые RGB и не обычное grayscale-преобразование.

Все аргументы этих трёх методов обязательны; скрытого default channel нет. Используйте конечные ограниченные числа, nonnegative radius и положительный sigma в обычной политике приложения. Radius=0 — разрешённый автоматический выбор. Совет radius>sigma для явного emboss-ядра — рекомендация качества, не обязательная проверка wrapper. Для elevation разумный интерфейс подбора может ограничить 0..90°, azimuth привести к одному обороту; это политика приложения, не объявление пределов PHP-API.

Изменение размера входа меняет отношение радиуса к буквам и границам. Большее ядро не равно лучшему рисунку; оно также требует ресурсов. RGB и intensity различаются: shade получает наклоны по интенсивности, а false затем масштабирует исходные компоненты; edge/emboss могут оставить цветные отклики.

Не принять все перепады за силуэт товара

Контурный просмотр: шумная бумага и Gaussian→edge, внешний макет сохранён
Контурный просмотр: шумная бумага и Gaussian→edge, внешний макет сохранён

На постоянных внутренних участках плашки 64/192 edge даёт нулевой отклик, у перепада положительный. Белая линия не означает завершённую границу объекта: буквы, фактура, блики и шум тоже имеют перепады. Edge не заполняет внутренние дырки и не расширяет alpha по связности.

В пустой части ярлыка x=80..219,y=177..185 нет букв. Средний R там измеряет ложный контурный отклик именно по конструкции входа; после сглаживания он должен уменьшиться. При этом буквы и тонкую линию нужно смотреть отдельно. Меньшее число на пустой бумаге не является общим качеством или результатом OCR.

В сохранённых PNG8 средний R пустой бумаги после edge равен 25.50, после Gaussian→edge — 2.38. На постоянных внутренних участках плашки 64/192 сохранены нулевые значения edge, на яркой стороне скачка — 255. Обрезка допустимого диапазона скрывает величину сильного положительного отклика; это не измерение исходной высоты перепада по значению 255.

Отделить оформительский рельеф от настоящей поверхности

Два требования: полный цветной emboss и явно серая вставка коробки с отдельной гистограммой
Два требования: полный цветной emboss и явно серая вставка коробки с отдельной гистограммой
Одинаковая elevation, противоположный azimuth: освещение условных склонов меняется
Одинаковая elevation, противоположный azimuth: освещение условных склонов меняется
При одном свете gray=true выдаёт освещённость, false масштабирует исходные каналы
При одном свете gray=true выдаёт освещённость, false масштабирует исходные каналы

Серая плашка — искусственная «ступенька с фаской»: фон 64, плоская вершина 192, переход шириной 6 пикселей. Цветная плашка построена из того же скалярного рисунка как (v,0.55v,0.22v) с округлением, но её интенсивность отличается; это не равные карты нормалей. На реальной фотографии тёмная краска не означает углубление, поэтому светотеневой эффект остаётся оформлением.

Emboss дополнительно выравнивает распределение внутри обрабатываемого изображения: вырезка и полный кадр дают разные условия. При локальном эскизе коробки все пиксели вне x=42..227,y=80..197 сохранены точно, включая SKU, кружку и нижние образцы. Ярлык edge обрабатывается отдельно в x=72..227,y=140..189. Граница ROI жёсткая; для мягкого перехода нужна отдельная осмысленная маска смешивания.

На серых контрольных склонах (31,278) и (106,278) shade с true/135°/45° дал 205 и 144; на плоской вершине — 180. При false/135°/45° эти склоны дали 103/72, при false/315°/45° — 72/103: яркая сторона поменялась. На цветной плоской вершине исходные (192,106,42) стали (135,74,29) при false и (180,180,180) при true с тем же светом. Это фактические значения PNG8 этого входа, с квантизацией при сохранении.

Проверить полезность и ограничения опыта

До обработки определите результат: карта перепадов, рельефная вставка или декоративное освещение. Проверяйте одинаковые участки и масштаб, читаемость SKU/букв, цвет и alpha; сохраняйте промежуточную версию. True и одинаковый размер PNG не доказывают пригодность результата.

Основные программы выполнены на PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 Q16. Результат сохранён как непрозрачный RGB PNG8, поэтому уровни квантуются. Малый опыт подтвердил возврат/ошибку пустого объекта, цветной emboss, явную grayscale-подготовку, градусы обоих углов и отличие EDGE/TILE; это ограниченные проверки, не полное независимое воспроизведение алгоритмов.

В той же проверке alpha-шахматка изменилась у edge, emboss и обеих ветвей shade. Эти сигнатуры не предлагают channel-аргумент для её сохранения; непрозрачный основной вход не доказывает произвольную прозрачность. Виртуальные пиксели влияют на рамку, а crop создаёт новую рамку. Для иной среды проверьте профиль/цветовое пространство/разрядность и необходимую политику alpha отдельно.

До обработки внешнего файла ограничьте формат, площадь и число кадров, проверьте конечность/предел параметров и права записи. Несколько clone и большое ядро требуют native-памяти. Чтение, эффект и запись обрабатывайте как отдельные отказы; в веб-ответе не раскрывайте внутренние пути. Сравнительной скорости без измерений не обещаем.

Выбрать преобразование и сделать свой вариант

Выбор по цели: перепады, рельеф или свет; защищённая область и оригинал остаются отдельными
Выбор по цели: перепады, рельеф или свет; защищённая область и оригинал остаются отдельными
  • Нужен контурный просмотр: edge, затем проверка шума и букв; не внешняя alpha-обводка.
  • Нужна рельефная вставка: явная подготовка цвета, emboss и точная ROI.
  • Нужна светотень: осмысленный яркостный вход, gray-режим и оба угла в градусах.
  • Нужно сохранить SKU: ограничьте область и сравните каждый внешний пиксель.

Упражнение: сделать серый рельеф только на цветной области коробки, сохранив SKU и кружку. Решение: clone; cropImage(186,118,42,80); setImagePage(0,0,0,0); transformImageColorspace(COLORSPACE_GRAY); embossImage(0,1); composite обратно в (42,80). Полная программа — локальный emboss. Затем объясните, почему обработка всего кадра и вырезки различается даже при одинаковых radius/sigma.

Продолжение: маска и локальная статистика, Gaussian и резкость, пороговая бинаризация, цветовые варианты. Следующий собственный макет начинайте с исходника и одной проверяемой цели.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

Imagick::edgeImageПоказать перепады макета и отделить полезные линии от шума.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::edgeImage(float $radius): bool

Показать перепады макета и отделить полезные линии от шума.

Уровни 0..255 на схеме — значения отображаемого PNG8, не реальные миллиметры высоты. Radius — радиус соседства в пикселях, sigma — стандартное отклонение Gaussian в пикселях; 0 у radius означает автоматический выбор. Azimuth — направление условного света, elevation — угол возвышения: оба в градусах. Gray=true выводит освещённость, false умножает на неё исходные RGB. Q означает QuantumRange, максимум внутреннего канала: в проверенной Q16-сборке 65535; углы и radius на Q не умножают. Координата x растёт вправо, y вниз.

Свёртка усиливает локальную разницу центра и соседей. Для radius=1 в точной сборке используется 3×3: восемь весов −1, центральный +8. Сумма на постоянном участке равна 0; отрицательные значения ограничиваются допустимым диапазоном. Результат не равен Canny, сегментации или равномерной внешней обводке.

Модель трёх численных правил; условная яркость не равна физической высоте
Модель трёх численных правил; условная яркость не равна физической высоте

Самая маленькая запись

В $image уже находится загруженная копия. 1 — радиус в пикселях, не толщина внешнего stroke. 0 разрешил бы автоматический размер. Стрелка -> вызывает метод объекта, круглые скобки содержат аргументы, запятые их отделяют, ; завершает команду.

$image->edgeImage(1);

Чтобы сохранить оригинал, сначала $image = clone $source; создаёт независимую копию, простое присваивание объект не копирует. Метод меняет текущую картинку. В полном коде if с ! проверяет false, throw new RuntimeException прекращает отказавшую цепочку; clear освобождает native-ресурсы после сохранения. Подготовка: объекты и методы, clone, исключения.

Сигнатура и все параметры

Imagick::edgeImage(float $radius): bool

Свёртка усиливает локальную разницу центра и соседей. Для radius=1 в точной сборке используется 3×3: восемь весов −1, центральный +8. Сумма на постоянном участке равна 0; отрицательные значения ограничиваются допустимым диапазоном. Результат не равен Canny, сегментации или равномерной внешней обводке.

АргументСмысл, единицы и обязательность
$radiusОбязательный float, радиус операции в пикселях. 0 автоматически выбирает размер ядра; 1 выбран для понятного 3×3. Это не толщина внешней рамки или число объектов.

Все параметры обязательны, default-аргументов нет. Дополнительного channel в этих трёх сигнатурах нет: нельзя дописать канал как у adaptive/статистических фильтров. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.

Возврат, отказ и границы

Тип результата bool: true при успехе, не новый Imagick. $ok = $image->edgeImage(...) сохранит флаг, а изображение останется в $image. Пустой Imagick в проверенной версии даёт ImagickException; native-отказ обвязка также переводит в исключение. Чтение, native-память и запись могут отказать отдельно. True подтверждает выполнение операции, не полезность изображения.

Обрабатывается текущий кадр; для последовательности нужен отдельный осмысленный проход. Размеры остаются прежними. Основные примеры — непрозрачный RGB PNG8; произвольная alpha, ICC/CMYK/HDR и многокадровые файлы не покрыты этим опытом. На тестовой переменной alpha-шахматке все три метода изменили alpha; общей гарантии её сохранения нет.

Сохранённые результаты: Получить контурный просмотр каталожного макета
Сохранённые результаты: Получить контурный просмотр каталожного макета
Получить контурный просмотр каталожного макетаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->edgeImage(1)) {
    throw new RuntimeException('Не удалось применить edgeImage');
}
saveReliefComparison([$source, $image], 'relief-edge-basic.png');
$source->clear();
$image->clear();

Результат: Панели: исходник, edge с радиусом 1 пиксель. Ровные внутренние участки перепада становятся чёрными, возле скачка виден положительный отклик. Текст и шум также создают отклик; это не автоматически выделенный силуэт предмета и не векторная обводка. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 800×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-edge-basic.png

Когда меняется требование

На бумаге зерно порождает множество лишних контуров. Сравним edge напрямую и после Gaussian 0/1 на независимых копиях того же ярлыка; внешний макет и SKU должны остаться точными.

CropImage(width,height,x,y) вырезает известный прямоугольник; setImagePage(0,0,0,0) сбрасывает его виртуальное смещение. CompositeImage(...,COMPOSITE_OVER,x,y) возвращает непрозрачную вырезку на clone исходника. Вне прямоугольника сохраняются точные пиксели. || означает «или»: отказ любой вставки прекращает цепочку.

У второй копии перед edge вызывается gaussianBlurImage(0,1): 0 — автоматический радиус, 1 — sigma в пикселях. Подготовка снижает мелкие перепады, включая полезные. Связанный разбор: Gaussian blur.

Подготовить контуры шумного ярлыка без изменения остального макетаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
$label = clone $source;
$label->cropImage(156, 50, 72, 140);
$label->setImagePage(0, 0, 0, 0);
$label->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$smoothed = clone $label;
if (!$label->edgeImage(1)) {
    throw new RuntimeException('Не удалось применить edgeImage');
}
if (!$smoothed->gaussianBlurImage(0, 1)) {
    throw new RuntimeException('Не удалось применить gaussianBlurImage');
}
if (!$smoothed->edgeImage(1)) {
    throw new RuntimeException('Не удалось применить edgeImage');
}
$prepared = clone $source;
if (!$image->compositeImage($label, Imagick::COMPOSITE_OVER, 72, 140) || !$prepared->compositeImage($smoothed, Imagick::COMPOSITE_OVER, 72, 140)) {
    throw new RuntimeException('Не удалось вернуть ярлык');
}
$label->clear();
$smoothed->clear();
saveReliefComparison([$source, $image, $prepared], 'relief-edge-label.png');
$source->clear();
$image->clear();
$prepared->clear();

Результат: Панели: исходник; edge ярлыка; Gaussian→edge ярлыка. В известном пустом участке отклик шума стал меньше, но сглаживание может ослабить нужные тонкие штрихи. Все пиксели вне x=72..227,y=140..189 совпадают с исходником. Это контурный просмотр, не OCR. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 1200×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-edge-label.png

Проверка и следующий выбор

Оставляйте исходник отдельно. Эти операции могут усилить JPEG-артефакты, стереть цветовую информацию, создать слишком резкий контур или изменить alpha. Не используйте radius как замену внешней обводке и не выдавайте светотень за геометрию товара. Если задача — исправить маску, полезен локальный максимум и его цена; если подавить зерно — адаптивные и selective-фильтры.

Связанные методы: embossImage · shadeImage.

Imagick::embossImageСделать оформительский рельеф всего кадра или серой вставки коробки.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::embossImage(float $radius, float $sigma): bool

Сделать оформительский рельеф всего кадра или серой вставки коробки.

Уровни 0..255 на схеме — значения отображаемого PNG8, не реальные миллиметры высоты. Radius — радиус соседства в пикселях, sigma — стандартное отклонение Gaussian в пикселях; 0 у radius означает автоматический выбор. Azimuth — направление условного света, elevation — угол возвышения: оба в градусах. Gray=true выводит освещённость, false умножает на неё исходные RGB. Q означает QuantumRange, максимум внутреннего канала: в проверенной Q16-сборке 65535; углы и radius на Q не умножают. Координата x растёт вправо, y вниз.

Точный Core создаёт направленное знаковое ядро из Gaussian-выражения, оставляет антидиагональные веса, нормирует их, делает ConvolveImage и затем EqualizeImage. Перепады получают светлую/тёмную подачу; распределение уровней меняется на всей обрабатываемой области. Это модель численных данных, не измерение высоты поверхности.

Модель трёх численных правил; условная яркость не равна физической высоте
Модель трёх численных правил; условная яркость не равна физической высоте

Самая маленькая запись

В $image уже находится загруженная копия. 0 — автоматический радиус, 1 — sigma в пикселях; оба аргумента обязательны. Стрелка -> вызывает метод объекта, круглые скобки содержат аргументы, запятые их отделяют, ; завершает команду.

$image->embossImage(0, 1);

Чтобы сохранить оригинал, сначала $image = clone $source; создаёт независимую копию, простое присваивание объект не копирует. Метод меняет текущую картинку. В полном коде if с ! проверяет false, throw new RuntimeException прекращает отказавшую цепочку; clear освобождает native-ресурсы после сохранения. Подготовка: объекты и методы, clone, исключения.

Сигнатура и все параметры

Imagick::embossImage(float $radius, float $sigma): bool

Точный Core создаёт направленное знаковое ядро из Gaussian-выражения, оставляет антидиагональные веса, нормирует их, делает ConvolveImage и затем EqualizeImage. Перепады получают светлую/тёмную подачу; распределение уровней меняется на всей обрабатываемой области. Это модель численных данных, не измерение высоты поверхности.

АргументСмысл, единицы и обязательность
$radiusОбязательный float: радиус в пикселях. 0 — автоматический подбор. Официальный совет radius больше sigma относится к разумному явному ядру, не к жёсткой проверке PHP.
$sigmaОбязательный float: стандартное отклонение Gaussian-оператора в пикселях. В примерах 1. При изменении масштаба исходника действие на детали меняется.

Все параметры обязательны, default-аргументов нет. Дополнительного channel в этих трёх сигнатурах нет: нельзя дописать канал как у adaptive/статистических фильтров. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.

Возврат, отказ и границы

Тип результата bool: true при успехе, не новый Imagick. $ok = $image->embossImage(...) сохранит флаг, а изображение останется в $image. Пустой Imagick в проверенной версии даёт ImagickException; native-отказ обвязка также переводит в исключение. Чтение, native-память и запись могут отказать отдельно. True подтверждает выполнение операции, не полезность изображения.

Обрабатывается текущий кадр; для последовательности нужен отдельный осмысленный проход. Размеры остаются прежними. Основные примеры — непрозрачный RGB PNG8; произвольная alpha, ICC/CMYK/HDR и многокадровые файлы не покрыты этим опытом. На тестовой переменной alpha-шахматке все три метода изменили alpha; общей гарантии её сохранения нет.

Сохранённые результаты: Создать отдельный рельефный вариант цветного макета
Сохранённые результаты: Создать отдельный рельефный вариант цветного макета
Создать отдельный рельефный вариант цветного макетаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->embossImage(0, 1)) {
    throw new RuntimeException('Не удалось применить embossImage');
}
saveReliefComparison([$source, $image], 'relief-emboss-basic.png');
$source->clear();
$image->clear();

Результат: Справа emboss с автоматическим radius=0 и sigma=1 пиксель. Перепады получают направленную светотеневую подачу и последующее выравнивание распределения. В этой сборке цветной вход дал цветные RGB-значения: метод не гарантирует серый результат и не возвращает новый Imagick. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 800×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-emboss-basic.png

Когда меняется требование

Для оформительского эскиза меняется только известная цветная область коробки 186×118. Сначала явно переводим её значения в серый, затем emboss и вставка обратно; служебную маркировку, кружку и образцы сохраняем.

CropImage(width,height,x,y) вырезает известный прямоугольник; setImagePage(0,0,0,0) сбрасывает его виртуальное смещение. CompositeImage(...,COMPOSITE_OVER,x,y) возвращает непрозрачную вырезку на clone исходника. Вне прямоугольника сохраняются точные пиксели. || означает «или»: отказ любой вставки прекращает цепочку.

TransformImageColorspace(Imagick::COLORSPACE_GRAY) действительно преобразует значения цветной вырезки в серый. :: читает именованную константу цвета. Это отличается от простой смены метки пространства; после emboss нейтральность результата проверяется по сохранённым RGB. Область Equalize тоже изменилась, поэтому полнокадровый и локальный примеры не сравнивают только один фактор.

Сделать серую рельефную вставку на коробке и защитить SKUПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
$region = clone $source;
$region->cropImage(186, 118, 42, 80);
$region->setImagePage(0, 0, 0, 0);
if (!$region->transformImageColorspace(Imagick::COLORSPACE_GRAY)) {
    throw new RuntimeException('Не удалось применить transformImageColorspace');
}
if (!$region->embossImage(0, 1)) {
    throw new RuntimeException('Не удалось применить embossImage');
}
if (!$image->compositeImage($region, Imagick::COMPOSITE_OVER, 42, 80)) {
    throw new RuntimeException('Не удалось вернуть вставку');
}
$region->clear();
saveReliefComparison([$source, $image], 'relief-emboss-inset.png');
$source->clear();
$image->clear();

Результат: Справа только x=42..227,y=80..197 превращены в серую рельефную вставку; вне области всё сохранено точно. Это другой сценарий, а не контролируемый тест одного преобразования gray: Equalize внутри emboss видит гистограмму вырезки, отличную от всего кадра. Результат не прогнозирует физическое тиснение. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 800×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-emboss-inset.png

Проверка и следующий выбор

Оставляйте исходник отдельно. Эти операции могут усилить JPEG-артефакты, стереть цветовую информацию, создать слишком резкий контур или изменить alpha. Не используйте radius как замену внешней обводке и не выдавайте светотень за геометрию товара. Если задача — исправить маску, полезен локальный максимум и его цена; если подавить зерно — адаптивные и selective-фильтры.

Связанные методы: edgeImage · shadeImage.

Imagick::shadeImageВыбрать светотеневой рисунок для заданного яркостного входа.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::shadeImage(bool $gray, float $azimuth, float $elevation): bool

Выбрать светотеневой рисунок для заданного яркостного входа.

Уровни 0..255 на схеме — значения отображаемого PNG8, не реальные миллиметры высоты. Radius — радиус соседства в пикселях, sigma — стандартное отклонение Gaussian в пикселях; 0 у radius означает автоматический выбор. Azimuth — направление условного света, elevation — угол возвышения: оба в градусах. Gray=true выводит освещённость, false умножает на неё исходные RGB. Q означает QuantumRange, максимум внутреннего канала: в проверенной Q16-сборке 65535; углы и radius на Q не умножают. Координата x растёт вправо, y вниз.

Из разностей интенсивности в окрестности 3×3 вычисляется условная нормаль — направление наклона. Её сопоставляют с вектором воображаемого далёкого света. Gray=true записывает вычисленную освещённость; false умножает на неё исходные обновляемые каналы. Ни одна ветвь не узнаёт настоящую форму или материал предмета.

Модель трёх численных правил; условная яркость не равна физической высоте
Модель трёх численных правил; условная яркость не равна физической высоте

Самая маленькая запись

В $image уже находится загруженная копия. True — записать освещённость, 135 — azimuth, 45 — elevation. Оба числа — градусы; это не координаты лампы в пикселях. Стрелка -> вызывает метод объекта, круглые скобки содержат аргументы, запятые их отделяют, ; завершает команду.

$image->shadeImage(true, 135, 45);

Чтобы сохранить оригинал, сначала $image = clone $source; создаёт независимую копию, простое присваивание объект не копирует. Метод меняет текущую картинку. В полном коде if с ! проверяет false, throw new RuntimeException прекращает отказавшую цепочку; clear освобождает native-ресурсы после сохранения. Подготовка: объекты и методы, clone, исключения.

Сигнатура и все параметры

Imagick::shadeImage(bool $gray, float $azimuth, float $elevation): bool

Из разностей интенсивности в окрестности 3×3 вычисляется условная нормаль — направление наклона. Её сопоставляют с вектором воображаемого далёкого света. Gray=true записывает вычисленную освещённость; false умножает на неё исходные обновляемые каналы. Ни одна ветвь не узнаёт настоящую форму или материал предмета.

АргументСмысл, единицы и обязательность
$grayОбязательный bool: true — освещённость, false — освещённость × исходные каналы. Это не просто команда обычного перевода фотографии в серый.
$azimuthОбязательный float, угол направления света в градусах относительно оси x. В примерах 135 и 315. Изображение имеет x вправо, y вниз; наблюдение контрольных склонов надёжнее угадывания стороны по фотографии.
$elevationОбязательный float, угол возвышения в градусах в проверенной реализации. Пример 45. Точный C переводит в радианы оба аргумента; единицы не пиксели и не QuantumRange.

Все параметры обязательны, default-аргументов нет. Дополнительного channel в этих трёх сигнатурах нет: нельзя дописать канал как у adaptive/статистических фильтров. Доступность PHP Manual: PECL imagick 2, PECL imagick 3.

Возврат, отказ и границы

Тип результата bool: true при успехе, не новый Imagick. $ok = $image->shadeImage(...) сохранит флаг, а изображение останется в $image. Пустой Imagick в проверенной версии даёт ImagickException; native-отказ обвязка также переводит в исключение. Чтение, native-память и запись могут отказать отдельно. True подтверждает выполнение операции, не полезность изображения.

Обрабатывается текущий кадр; для последовательности нужен отдельный осмысленный проход. Размеры остаются прежними. Основные примеры — непрозрачный RGB PNG8; произвольная alpha, ICC/CMYK/HDR и многокадровые файлы не покрыты этим опытом. На тестовой переменной alpha-шахматке все три метода изменили alpha; общей гарантии её сохранения нет.

Сохранённые результаты: Увидеть освещённость условного рельефа
Сохранённые результаты: Увидеть освещённость условного рельефа
Увидеть освещённость условного рельефаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->shadeImage(true, 135, 45)) {
    throw new RuntimeException('Не удалось применить shadeImage');
}
saveReliefComparison([$source, $image], 'relief-shade-gray.png');
$source->clear();
$image->clear();

Результат: Справа gray=true, azimuth=135°, elevation=45°. Обновляемые RGB-каналы содержат одинаковую вычисленную освещённость. Перепады интенсивности задают условные наклоны; исходный цвет не восстанавливается. Это синтетический светотеневой рисунок, а не реконструкция геометрии кружки. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 800×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-shade-gray.png

Когда меняется требование

Нужен цветной светотеневой вариант макета. Gray=false умножает исходные RGB на освещённость; сравниваем azimuth 135° и 315° при одинаковой elevation 45° на независимых копиях.

Противоположные azimuth 135°/315° при одинаковых gray=false и elevation=45°
Противоположные azimuth 135°/315° при одинаковых gray=false и elevation=45°

False выбирает умножение исходного цвета. 315−135=180° — половина оборота; elevation остаётся 45°, поэтому сравнивается направление, а не высота условного света. Обе копии берутся из $source; второй свет не накладывается поверх первого.

Выбрать направление освещения цветного декоративного вариантаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/relief-fixture.php';
$source = loadReliefSource();
$source->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_EDGE);
$image = clone $source;
if (!$image->shadeImage(false, 135, 45)) {
    throw new RuntimeException('Не удалось применить shadeImage');
}
$opposite = clone $source;
if (!$opposite->shadeImage(false, 315, 45)) {
    throw new RuntimeException('Не удалось применить shadeImage');
}
saveReliefComparison([$source, $image, $opposite], 'relief-shade-directions.png');
$source->clear();
$image->clear();
$opposite->clear();

Результат: Панели: исходник, false/135°/45°, false/315°/45°. У противоположных склонов серого контрольного рельефа светлая и тёмная сторона меняются местами. Цветная плашка остаётся цветной, но её значения изменены умножением. Для сравнения gray=true/false используйте тот же угол 135°/45° из минимального примера. Архив содержит example.php, relief-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске. Выходной PNG откройте обычным просмотрщиком; stdout содержит его имя. Первая панель — исходник, затем варианты в указанном порядке; размер 1200×320, каждая панель 400×320 без масштабирования. Подписи исходного растра описывают вход и не пересчитываются фильтром.

Ожидаемый вывод
relief-shade-directions.png

Проверка и следующий выбор

Оставляйте исходник отдельно. Эти операции могут усилить JPEG-артефакты, стереть цветовую информацию, создать слишком резкий контур или изменить alpha. Не используйте radius как замену внешней обводке и не выдавайте светотень за геометрию товара. Если задача — исправить маску, полезен локальный максимум и его цена; если подавить зерно — адаптивные и selective-фильтры.

Связанные методы: edgeImage · embossImage.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.