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

Дерево руководства
Глава 355 · После полей и рамок
Imagick: собственная тень, мягкий край и композиция
Прозрачный товар и готовая карточка с полной геометрией и явной alpha.
Сохранить готовую карточку с товаром и тенью
Нужна скачиваемая карточка товара: прозрачный силуэт стоит на выбранной подложке, под ним видна мягкая тень, а служебная маркировка читается. Оформление должно попасть в сам PNG для памятки или отправки. Для показа только на странице иногда достаточно CSS; здесь готовим самостоятельный файл.

В архиве есть второй вход product.png.b64: авторский прозрачный силуэт коробки и кружки, включая отверстие ручки и промежуточную alpha по краям. Эта готовая геометрическая маска не является алгоритмом автоматического удаления фона. Прозрачные места на белом preview выглядят белыми только из-за подложки просмотра.

Три разных шага: shadow строит по прозрачности отдельную тень; vignette смягчает край через маску эллипса; composite размещает один источник на другом. Тень не содержит сам товар. Перед схемой разберём её короткие обозначения:
| Термин | Значение в этом примере |
|---|---|
| Размеры и положение | W и H — ширина и высота; координаты x/y идут от нуля вправо/вниз. Page хранит виртуальные размеры и смещение. Сам bitmap — реальный массив пикселей, он может иметь другой размер. |
| Тень | Opacity 70 — 70 процентов, sigma 4 — 4 пикселя. Прозрачное поле b = floor(2×sigma+0.5) = 8 с каждой стороны; floor округляет вниз. Background — цвет тени. |
| Виньетка | Публичные blackPoint/whitePoint фактически radius/sigma, оба в пикселях. x/y уменьшают полуоси центрированного эллипса. Background — цвет подложки края. |
| Композиция | Alpha A — вклад пикселя от 0 до 1. OVER накладывает источник; DSTIN умножает alpha получателя на alpha источника. RGB хранит цвет отдельно от alpha. Возвращаемое true — bool, не изображение. |
Интенсивность — численная яркость, вычисленная из цветовых компонентов. Внутренний максимум Q = QuantumRange, здесь Q16 означает 65535. Файлы сохраняются с 8 битами на компоненту: RGB color-type 2 или RGBA color-type 6. Это не индексированный PNG; белая подложка preview не записывается в отдельные RGBA-файлы.
В формуле схемы Cs и As — RGB-цвет и alpha источника, Cd и Ad — RGB-цвет и alpha получателя, C и A — результат. Цветовая формула применяется отдельно к каждой RGB-компоненте и показана для непрозрачного получателя, Ad = 1.

Самая маленькая запись
В $image уже есть изображение. $ начинает имя переменной, -> вызывает её метод; круглые скобки содержат аргументы, запятые разделяют их, ; завершает команду. Imagick::COMPOSITE_OVER — именованная константа класса; :: здесь связывает имя класса и константу. Строки цветов записываются в кавычках. Берёт alpha текущего изображения, умножает её на opacity/100, окрашивает в background и размывает alpha с sigma. Сам товар исчезает: текущий объект становится тенью. Непрозрачная фотография даёт прямоугольник, прозрачный силуэт — форму товара. Это оформление, не расчёт физического освещения.
$image->shadowImage(70, 4, 12, 8);Присваивание $image = clone $source создаёт независимую копию, а простое $image = $source — ещё одно имя того же объекта. Результат метода нельзя присваивать вместо изображения: там bool. If проверяет условие, ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку. У composite true ограничено особенностью wrapper, описанной ниже. Подготовка: clone, объекты и методы, исключения.
Для полезной карточки нужен ещё один прямой вызов. $card — новый получатель 440×360, $product — вход 400×320; (20,20) задаёт его реальное положение. Тень должна лечь раньше товара, чтобы не затемнить его сверху.
$card = new Imagick();
$card->newImage(440, 360, '#e8eff4');
$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20);Для запуска нужны example.php, shadow-fixture.php, source.png.b64 и product.png.b64; распакуйте их вместе и сохраните остальные файлы архива. Начало <?php включает PHP, declare(strict_types=1) задаёт строгую передачу типов. Require подключает помощник из __DIR__, папки программы. Две load-функции проверяют Base64/SHA256, восстанавливают точные source.png и product.png и возвращают Imagick. ShadowPreview возвращает отдельный белый preview, сохраняя исходную alpha-фигуру. SaveShadowComparison собирает целые панели и печатает имя PNG. Слово function, return, массив и цикл помощника разобраны после работающего примера.
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$shadow = clone $product;
$shadow->setImageBackgroundColor('black');
if (!$shadow->shadowImage(70, 4, 12, 8)) {
throw new RuntimeException('Не выполнен shadowImage');
}
$shadow->setImageFormat('png');
$shadow->setImageDepth(8);
$shadow->setOption('png:color-type', '6');
if (!$shadow->writeImage(__DIR__ . '/first-shadow.png')) {
throw new RuntimeException('Не записан first-shadow.png');
}
$preview = shadowPreview($product);
$card = new Imagick();
$card->newImage(440, 360, '#e8eff4');
$page = $shadow->getImagePage();
if (!$card->compositeImage($shadow, Imagick::COMPOSITE_OVER, 20 + $page['x'], 20 + $page['y'])) {
throw new RuntimeException('Не выполнен compositeImage');
}
if (!$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20)) {
throw new RuntimeException('Не выполнен compositeImage');
}
saveShadowComparison([$source, $preview, $card], 'shadow-first.png');
$source->clear();
$preview->clear();
$card->clear();
$product->clear();
$shadow->clear();
Результат: Каталог, готовый прозрачный товар на белой подложке просмотра, затем карточка 440×360 с тенью и товаром. В first-shadow.png сохранена сама прозрачная тень 416×336. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит shadow-first.png и перевод строки. Размер сравнения 1240×360: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
shadow-first.png
Полный помощник shadow-fixture.php, включённый в каждый ZIP
<?php
declare(strict_types=1);
function loadShadowFixture(string $name, string $sha256): Imagick
{
$encoded = file_get_contents(__DIR__ . '/' . $name . '.b64');
if ($encoded === false) {
throw new RuntimeException('Распакуйте весь архив с двумя PNG в Base64');
}
$bytes = base64_decode($encoded, true);
if ($bytes === false || hash('sha256', $bytes) !== $sha256) {
throw new RuntimeException('Повреждён входной PNG');
}
$path = __DIR__ . '/' . $name;
if (file_put_contents($path, $bytes) !== strlen($bytes)) {
throw new RuntimeException('Не удалось восстановить входной PNG');
}
return new Imagick($path);
}
function loadShadowSource(): Imagick
{
return loadShadowFixture('source.png', '453b22e19273f2fdd54ec6a7f0cd9e96a7b08c70cc4cc854838d1428fea207c6');
}
function loadShadowProduct(): Imagick
{
return loadShadowFixture('product.png', 'f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c');
}
function shadowPreview(Imagick $image): Imagick
{
$preview = new Imagick();
$preview->newImage($image->getImageWidth(), $image->getImageHeight(), 'white');
$preview->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0);
return $preview;
}
function saveShadowComparison(array $panels, string $filename): void
{
if ($panels === []) {
throw new InvalidArgumentException('Нужна хотя бы одна панель');
}
$width = 0;
$height = 0;
foreach ($panels as $panel) {
$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);
$output->compositeImage($panel, Imagick::COMPOSITE_OVER, $left, $top);
$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 объявляет функцию, return возвращает её результат; : Imagick — тип возвращаемого изображения, void — отсутствие результата. Массив $panels хранит панели, foreach перебирает их. += суммирует фактические ширины, max выбирает наибольшую высоту, intdiv делит нацело для вертикального центрирования. File_get_contents читает строку Base64, base64_decode восстанавливает байты, hash проверяет их SHA256, file_put_contents сохраняет PNG. Помощник не скачивает файлы и не ищет шрифты. Подготовка: функции, массивы, циклы.
Разделить alpha, маску, page и размещение
Для sigma 4 поле b 8 даёт тень 416×336. В текущем объекте после вызова её page offset равен (4,0). При базовой позиции товара (20,20) размещаем полный растр тени в (24,20), а товар в (20,20): его alpha-форма внутри тени дополнительно смещена на 8 пикселей поля. Получается заданный сдвиг тени 12/8 относительно товара. Полный растр тени помещается в 440×360: правый край 440, нижний 356. Page не увеличивает получателя автоматически.
Код читает page у живого $shadow. В отдельных PNG тени эта сборка также сохранила служебную запись ImageMagick caNv с page (420,336,4,0). Другой читатель изображений может её не учитывать: храните нужное смещение явно в параметрах макета; для этих слоёв оно равно (4,0). Сохранённые RGBA-пиксели и виртуальная позиция — разные данные.
GetImagePage возвращает массив, $page["x"] читает значение ключа x. :: в Imagick::COMPOSITE_OVER обращается к константе класса; Imagick::getQuantumRange() — вызов статического метода класса, дающий сведения о внутреннем диапазоне. В коде карточки Q не нужен: проценты тени и пиксельные размеры уже заданы своими единицами.
У виньетки x30/y20 на 400×320 оставляют полуоси 170/140 и центр(200,160). Они не двигают эллипс к товару. OVER для непрозрачного фона можно понимать как A×цвет источника+(1−A)×цвет фона по компонентам; это ограниченная модель смешивания, не полный каталог операторов и цветоуправления. DSTIN вместо цвета источника использует его alpha.
До следующей полной программы: $shadow — clone прозрачного товара с background black; $vignette — clone каталога; $card — заранее созданная подложка. Все маленькие вызовы показаны отдельно:
$shadow->shadowImage(70, 4, 12, 8);
$vignette->vignetteImage(0, 18, 30, 20);
$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20);<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$shadow = clone $product;
$shadow->setImageBackgroundColor('black');
if (!$shadow->shadowImage(70, 4, 12, 8)) {
throw new RuntimeException('Не выполнен shadowImage');
}
$shadow->setImageFormat('png');
$shadow->setImageDepth(8);
$shadow->setOption('png:color-type', '6');
if (!$shadow->writeImage(__DIR__ . '/controls-shadow.png')) {
throw new RuntimeException('Не записан controls-shadow.png');
}
$shadowPreview = shadowPreview($shadow);
$vignette = clone $source;
$vignette->setImageBackgroundColor('black');
if (!$vignette->vignetteImage(0, 18, 30, 20)) {
throw new RuntimeException('Не выполнен vignetteImage');
}
$card = new Imagick();
$card->newImage(440, 360, '#e8eff4');
$page = $shadow->getImagePage();
if (!$card->compositeImage($shadow, Imagick::COMPOSITE_OVER, 20 + $page['x'], 20 + $page['y'])) {
throw new RuntimeException('Не выполнен compositeImage');
}
if (!$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20)) {
throw new RuntimeException('Не выполнен compositeImage');
}
saveShadowComparison([$source, $shadowPreview, $vignette, $card], 'shadow-controls.png');
$source->clear();
$shadowPreview->clear();
$vignette->clear();
$card->clear();
$product->clear();
$shadow->clear();
Результат: Исходник; только тень на белом фоне просмотра; виньетка всего каталога; готовая карточка. Все растры целиком и без изменения масштаба. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит shadow-controls.png и перевод строки. Размер сравнения 1656×360: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
shadow-controls.png
Выбрать тень силуэта или всей фотографии
Если исходник непрозрачен целиком, тень будет от прямоугольной фотографии. Если нужно отделить только товар, требуется настоящий alpha-силуэт до shadow. Сравниваем две осмысленные задачи: отдельный прозрачный слой для дальнейшего оформления и готовая фотокарточка с сохранённой маркировкой.


Первый вариант: сохранить отдельную тень. Фотокарточка использует ту же геометрию 70/4/12/8, но alpha входа полностью непрозрачна; поэтому её тень отличается по форме. Исходник в (20,20) сохраняет все 400×320 пикселей. Это не маска предмета и не физическая модель его освещения.
Смягчить фотографию и защитить служебный текст
Виньетка полезна, когда край иллюстрации должен плавно войти в тёмный или белый фон. Глобальный вызов затрагивает и надписи каталога: это видно в минимальном сравнении. Для рабочего макета оставим заголовок, SKU и нижние шкалы нетронутыми, обработав только иллюстрацию 352×132 в(24,88).

CropImage(352,132,24,88) принимает сначала ширину/высоту, затем x/y. SetImagePage(0,0,0,0) сбрасывает старую виртуальную позицию вырезки. После виньетки opaque-область накладывается обратно OVER в(24,88); вне известного прямоугольника исходные пиксели точны. Этот ROI задан автором макета, а не найден распознаванием. Два полных сценария: параметры и программы виньетки.
Наложить товар и применить готовую alpha-маску
OVER берёт цвет и alpha источника. DSTIN берёт alpha источника как маску для получателя. В нашем втором сценарии RGB product не определяет форму маски: форму задаёт его alpha. Серая картинка mask-alpha.png — лишь явное представление этой alpha для проверки человеком.

У исходного RGB-файла нет активной alpha. ALPHACHANNEL_ACTIVATE только включает канал и не гарантирует заполнение его нужным значением: в отдельной пробе он активировал нули, и DSTIN сделал всё прозрачным. Поэтому полный рабочий сценарий явно использует ALPHACHANNEL_OPAQUE — непрозрачный канал — перед умножением маской. ALPHACHANNEL_EXTRACT у копии product показывает её alpha серыми уровнями. Это именованные константы, не произвольные числа. Чёрный на этой серой карте означает alpha 0, белый alpha 1; RGB настоящей alpha-маски может быть любым.
Сохраняем masked-product.png как RGBA color-type 6; не заменяем alpha глобальным setImageOpacity. White preview отдельно показывает результат на белом. Для сайта можно отдать сохранённые PNG-байты с подходящим MIME; HTTP в этой локальной программе не проверяется. Два полных сценария: разместить товар и применить alpha-маску.
Проверить реальный PNG и отличить отказ от true
| Ситуация | Что проверить |
|---|---|
| Тень почти не видна | Opacity задаётся процентами:0.4 —0,4%,70 —70%. Сама прозрачная тень может быть невидимой на чёрном фоне просмотра. |
| x/y тени будто не работают | Сравните raster и page. При ручном composite используйте page offset и свою базовую позицию; не ожидайте автоматического роста canvas. |
| Виньетка не того цвета | Перед вызовом задайте background. Первые два аргумента — radius/sigma этой реализации, не значения чёрного и белого. |
| Маска дала пустой PNG | Проверьте alpha получателя до DSTIN; в нашем фиксированном сценарии нужен OPAQUE, не только ACTIVATE. |
| Composite вернул true | Проверьте настоящий результат и дополнительные аргументы оператора; bool wrapper 3.8.1 не отражает каждый native failure. |
| Нужна только рамка на странице | Возможно достаточно CSS; в файл оформление записывают, когда он должен переноситься вместе с PNG. |
Все основные сравнения непрозрачны и сохранены с 8 битами на RGB-компоненту; отдельные тени и masked-product имеют настоящую alpha. Сохранение JPEG её потеряет. Не переносим наблюдения alpha/цветовых каналов на любой оператор: в маленьком RED-контроле G/B взялись из источника, поэтому обещание «все остальные каналы получателя неизменны» неверно. Основные программы используют проверенный CHANNEL_DEFAULT. Для другой маски/цветового пространства нужно явно определить ожидаемое поведение.
При ошибке чтения, Base64, записи или проверяемого shadow/vignette код прерывается исключением. Composite проверяется дополнительно реальными PNG и семантическими пикселями, а не одним bool. Эти локальные тесты не измеряют физическую корректность тени, совместимость печати, размер файла или скорость. Внешняя форма загрузки и проверка недоверенных файлов не реализованы.
Выбрать свой маршрут оформления

Упражнение: перенесите товар в(16,12) на такой же карточке, сохранив сдвиг тени 12/8. Решение: page offset остаётся(4,0), поэтому тень размещается в (20,12), товар в(16,12). Для непрозрачной фотографии исходные 400×320 пикселей должны находиться точно в(16,12). Проверьте, что весь 416×336 растр тени помещается в 440×360. Не меняйте x/y shadow только ради ручного переноса всей группы — измените базовую позицию композиции.
Следующий шаг: поля и рамка в самом PNG, палитры и таблицы до оформления, геометрия и полный изменённый холст, надёжная запись файлов. Сначала определите, нужен готовый прозрачный слой, отдельный файл карточки или только внешний вид страницы.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::shadowImageБерёт alpha текущего изображения, умножает её на opacity/100, окрашивает в background и размывает alpha с sigma. Сам товар исчезает: текущий объект становится тенью. Непрозрачная фотография даёт прямоугольник, прозрачный силуэт — форму товара. Это оформление, не расчёт физического освещения.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::shadowImage(float $opacity, float $sigma, int $x, int $y): boolСамая маленькая запись
В $image уже есть изображение. $ начинает имя переменной, -> вызывает её метод; круглые скобки содержат аргументы, запятые разделяют их, ; завершает команду. Imagick::COMPOSITE_OVER — именованная константа класса; :: здесь связывает имя класса и константу. Строки цветов записываются в кавычках. Берёт alpha текущего изображения, умножает её на opacity/100, окрашивает в background и размывает alpha с sigma. Сам товар исчезает: текущий объект становится тенью. Непрозрачная фотография даёт прямоугольник, прозрачный силуэт — форму товара. Это оформление, не расчёт физического освещения.
$image->shadowImage(70, 4, 12, 8);Присваивание $image = clone $source создаёт независимую копию, а простое $image = $source — ещё одно имя того же объекта. Результат метода нельзя присваивать вместо изображения: там bool. If проверяет условие, ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку. У composite true ограничено особенностью wrapper, описанной ниже. Подготовка: clone, объекты и методы, исключения.
Полная сигнатура и все аргументы
Imagick::shadowImage(float $opacity, float $sigma, int $x, int $y): bool| Аргумент | Смысл, единицы и границы |
|---|---|
| $opacity | Обязательный float, проценты alpha. Здесь 70 означает 70%; 0.4 из официального примера означает 0,4%, а не 40%. |
| $sigma | Обязательный float, стандартное отклонение размытия в пикселях; здесь 4. В точном Core прозрачное поле b=floor(2×sigma+0.5), по b с каждой стороны: 400×320 → 416×336. |
| $x / $y | Два обязательных int, пиксельные смещения virtual page. Не перемещают пиксели внутри массива растра. Здесь (12,8) дают page offset (4,0) после поля b 8. Для ручной композиции читаем page и прибавляем базовую позицию товара. |
Официальная доступность: PECL imagick 2, PECL imagick 3. Публичный результат bool true; операция изменяет текущий объект, а не возвращает новый Imagick. Неверное число или тип аргументов может дать PHP-ошибку. Пустое изображение проверяется wrapper и вызывает ImagickException; пустая секция errors в XML не обещает отсутствия исключений.
Все четыре аргумента обязательны, channel-аргумента нет. Нативный отказ конвертируется в ImagickException. Цвет тени задаём setImageBackgroundColor("black") до вызова. В сохранённой пробе 70 дало максимум alpha 45875/Q, а официальный 0.4 — 262/Q. При одинаковой sigma смена x/y сохранила RGBA-пиксели и изменила page. Для текущего объекта после вызова с (12,8) page равен 420×336+(4,0), но raster — 416×336; page зависит и от входного состояния, не является универсальным размером файла. В наших PNG он сохранён служебной записью caNv; совместимость этой записи с любым читателем не гарантируется.
Значения в программах фиксированы и умеренны. Для внешних данных отдельно ограничивают площадь полотен и число кадров, проверяют конечные неотрицательные sigma/radius, долю opacity 0..100, допустимые полуоси и whitelist операторов. Система такой валидации здесь не реализована. Издержки зависят от площади, копий и размытия; скорость или уменьшение файла не измерялись.
Полный официальный XML: описание, параметры, returns, пример и ссылки
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.shadowimage">
<refnamediv>
<refname>Imagick::shadowImage</refname>
<refpurpose>Simulates an image shadow</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::shadowImage</methodname>
<methodparam><type>float</type><parameter>opacity</parameter></methodparam>
<methodparam><type>float</type><parameter>sigma</parameter></methodparam>
<methodparam><type>int</type><parameter>x</parameter></methodparam>
<methodparam><type>int</type><parameter>y</parameter></methodparam>
</methodsynopsis>
<para>
Simulates an image shadow.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>opacity</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>sigma</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>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::shadowImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function shadowImage($imagePath) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->shadowImage(0.4, 10, 50, 5);
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
-->
Официальные HTTP-примеры сохранены целиком. Header задаёт MIME, но сам не преобразует PNG в JPEG; JPEG не хранит alpha. Наши программы сохраняют локальные PNG и не являются проверкой веб-выдачи. Основы: файлы, HTTP-ответ.
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$shadow = clone $product;
$shadow->setImageBackgroundColor('black');
if (!$shadow->shadowImage(70, 4, 12, 8)) {
throw new RuntimeException('Не выполнен shadowImage');
}
$shadow->setImageFormat('png');
$shadow->setImageDepth(8);
$shadow->setOption('png:color-type', '6');
if (!$shadow->writeImage(__DIR__ . '/shadow-only.png')) {
throw new RuntimeException('Не записан shadow-only.png');
}
$preview = shadowPreview($shadow);
saveShadowComparison([$source, $preview], 'shadow-only-comparison.png');
$source->clear();
$preview->clear();
$product->clear();
$shadow->clear();
Результат: Каталог и отдельная тень на белом фоне просмотра; shadow-only.png — настоящая RGBA-тень 416×336 для дальнейшей композиции, без самого товара. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит shadow-only-comparison.png и перевод строки. Размер сравнения 816×336: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
shadow-only-comparison.png
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$shadow = clone $source;
$shadow->setImageBackgroundColor('black');
if (!$shadow->shadowImage(70, 4, 12, 8)) {
throw new RuntimeException('Не выполнен shadowImage');
}
$shadow->setImageFormat('png');
$shadow->setImageDepth(8);
$shadow->setOption('png:color-type', '6');
if (!$shadow->writeImage(__DIR__ . '/photo-shadow.png')) {
throw new RuntimeException('Не записан photo-shadow.png');
}
$card = new Imagick();
$card->newImage(440, 360, '#e8eff4');
$page = $shadow->getImagePage();
if (!$card->compositeImage($shadow, Imagick::COMPOSITE_OVER, 20 + $page['x'], 20 + $page['y'])) {
throw new RuntimeException('Не выполнен compositeImage');
}
if (!$card->compositeImage($source, Imagick::COMPOSITE_OVER, 20, 20)) {
throw new RuntimeException('Не выполнен compositeImage');
}
saveShadowComparison([$source, $card], 'shadow-photo-card.png');
$source->clear();
$card->clear();
$product->clear();
$shadow->clear();
Результат: Слева исходник; справа полная фотокарточка 440×360. Прямоугольная тень идёт от всей непрозрачной фотографии, а не только от кружки. Исходные 400×320 пикселей сохранены в (20,20). Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит shadow-photo-card.png и перевод строки. Размер сравнения 840×360: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
shadow-photo-card.png
Связанный путь: модель alpha, page и размещения, границы и ошибки.
Imagick::vignetteImageСоздаёт центрированный белый эллипс на чёрной карте, размывает её и использует интенсивность как мягкую маску, затем сводит изображение с background. Это мягкое оформление края, не автоматическое распознавание предмета.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::vignetteImage(float $blackPoint, float $whitePoint, int $x, int $y): boolСамая маленькая запись
В $image уже есть изображение. $ начинает имя переменной, -> вызывает её метод; круглые скобки содержат аргументы, запятые разделяют их, ; завершает команду. Imagick::COMPOSITE_OVER — именованная константа класса; :: здесь связывает имя класса и константу. Строки цветов записываются в кавычках. Создаёт центрированный белый эллипс на чёрной карте, размывает её и использует интенсивность как мягкую маску, затем сводит изображение с background. Это мягкое оформление края, не автоматическое распознавание предмета.
$image->vignetteImage(0, 18, 30, 20);Присваивание $image = clone $source создаёт независимую копию, а простое $image = $source — ещё одно имя того же объекта. Результат метода нельзя присваивать вместо изображения: там bool. If проверяет условие, ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку. У composite true ограничено особенностью wrapper, описанной ниже. Подготовка: clone, объекты и методы, исключения.
Полная сигнатура и все аргументы
Imagick::vignetteImage(float $blackPoint, float $whitePoint, int $x, int $y): bool| Аргумент | Смысл, единицы и границы |
|---|---|
| $blackPoint | Обязательный float. Официальное имя сохранено, но в этой реализации передаётся как radius размытия маски, в пикселях. 0 выбирает подходящий радиус автоматически; это не чёрная точка в Q. |
| $whitePoint | Обязательный float, фактически sigma в пикселях. В полном кадре 18, в небольшой области 12. Это не белая точка и не процент. |
| $x / $y | Два обязательных int, отступы полуосей от половины ширины/высоты. Эллипс имеет центр(W/2,H/2), полуоси(W/2−x,H/2−y). x30/y20 для 400×320 дают 170/140. Они не сдвигают центр. |
Официальная доступность: PECL imagick 2, PECL imagick 3. Публичный результат bool true; операция изменяет текущий объект, а не возвращает новый Imagick. Неверное число или тип аргументов может дать PHP-ошибку. Пустое изображение проверяется wrapper и вызывает ImagickException; пустая секция errors в XML не обещает отсутствия исключений.
Метод доступен при компиляции с ImageMagick6.2.9 или новее. Все четыре аргумента обязательны; channel нет, native failure даёт ImagickException. Полный raw-контракт с именами blackPoint/whitePoint оставлен без исправления; точный wrapper передаёт их в native radius/sigma. Flatten использует background и может изменить alpha. Непрозрачность наших итоговых сравнений нельзя переносить как гарантию сохранения произвольной прозрачности.
Значения в программах фиксированы и умеренны. Для внешних данных отдельно ограничивают площадь полотен и число кадров, проверяют конечные неотрицательные sigma/radius, долю opacity 0..100, допустимые полуоси и whitelist операторов. Система такой валидации здесь не реализована. Издержки зависят от площади, копий и размытия; скорость или уменьшение файла не измерялись.
Полный официальный XML: описание, параметры, returns, пример и ссылки
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.vignetteimage">
<refnamediv>
<refname>Imagick::vignetteImage</refname>
<refpurpose>Adds vignette filter to the image</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::vignetteImage</methodname>
<methodparam><type>float</type><parameter>blackPoint</parameter></methodparam>
<methodparam><type>float</type><parameter>whitePoint</parameter></methodparam>
<methodparam><type>int</type><parameter>x</parameter></methodparam>
<methodparam><type>int</type><parameter>y</parameter></methodparam>
</methodsynopsis>
<para>
Softens the edges of the image in vignette style.
&imagick.method.available.0x629;
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>blackPoint</parameter></term>
<listitem>
<para>
The black point.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>whitePoint</parameter></term>
<listitem>
<para>
The white point
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>x</parameter></term>
<listitem>
<para>
X offset of the ellipse
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>y</parameter></term>
<listitem>
<para>
Y offset of the ellipse
</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::vignetteImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function vignetteImage($imagePath, $blackPoint, $whitePoint, $x, $y) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->vignetteImage($blackPoint, $whitePoint, $x, $y);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
}
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>Imagick::waveImage</function></member>
<member><function>Imagick::swirlImage</function></member>
</simplelist>
</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
-->
Официальные HTTP-примеры сохранены целиком. Header задаёт MIME, но сам не преобразует PNG в JPEG; JPEG не хранит alpha. Наши программы сохраняют локальные PNG и не являются проверкой веб-выдачи. Основы: файлы, HTTP-ответ.
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$image = clone $source;
$image->setImageBackgroundColor('black');
if (!$image->vignetteImage(0, 18, 30, 20)) {
throw new RuntimeException('Не выполнен vignetteImage');
}
$white = clone $source;
$white->setImageBackgroundColor('white');
if (!$white->vignetteImage(0, 18, 30, 20)) {
throw new RuntimeException('Не выполнен vignetteImage');
}
saveShadowComparison([$source, $image, $white], 'vignette-backgrounds.png');
$source->clear();
$image->clear();
$white->clear();
$product->clear();
Результат: Каталог, виньетка на чёрном фоне, та же геометрия на белом фоне. Размер каждой панели остаётся 400×320; фон меняет результат, это не просто уменьшение RGB по краям. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит vignette-backgrounds.png и перевод строки. Размер сравнения 1200×320: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
vignette-backgrounds.png
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$image = clone $source;
$region = clone $source;
$region->cropImage(352, 132, 24, 88);
$region->setImagePage(0, 0, 0, 0);
$region->setImageBackgroundColor('#e8eff4');
if (!$region->vignetteImage(0, 12, 20, 12)) {
throw new RuntimeException('Не выполнен vignetteImage');
}
if (!$image->compositeImage($region, Imagick::COMPOSITE_OVER, 24, 88)) {
throw new RuntimeException('Не выполнен compositeImage');
}
saveShadowComparison([$source, $image], 'vignette-protected.png');
$source->clear();
$image->clear();
$product->clear();
$region->clear();
Результат: Виньетка применена только к прямоугольнику x24/y88/352×132, затем он возвращён на место. Заголовок, SKU и нижние шкалы вне него сохраняют исходные пиксели. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит vignette-protected.png и перевод строки. Размер сравнения 800×320: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
vignette-protected.png
Связанный путь: модель alpha, page и размещения, границы и ошибки.
Imagick::compositeImageТекущий объект — получатель, первый аргумент — накладываемый источник. OVER смешивает их по alpha источника; DSTIN использует alpha источника как множитель alpha получателя. Порядок важен. Получатель не растёт, выходящие за его границы части источника отсекаются.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::compositeImage(Imagick $composite_object, int $composite, int $x, int $y, int $channel = Imagick::CHANNEL_DEFAULT): boolСамая маленькая запись
В $card уже есть изображение; $product — отдельный источник с alpha. $ начинает имя переменной, -> вызывает её метод; круглые скобки содержат аргументы, запятые разделяют их, ; завершает команду. Imagick::COMPOSITE_OVER — именованная константа класса; :: здесь связывает имя класса и константу. Строки цветов записываются в кавычках. Текущий объект — получатель, первый аргумент — накладываемый источник. OVER смешивает их по alpha источника; DSTIN использует alpha источника как множитель alpha получателя. Порядок важен. Получатель не растёт, выходящие за его границы части источника отсекаются.
$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20);Присваивание $image = clone $source создаёт независимую копию, а простое $image = $source — ещё одно имя того же объекта. Результат метода нельзя присваивать вместо изображения: там bool. If проверяет условие, ! означает отрицание; throw new RuntimeException прерывает отказавшую цепочку. У composite true ограничено особенностью wrapper, описанной ниже. Подготовка: clone, объекты и методы, исключения.
Полная сигнатура и все аргументы
Imagick::compositeImage(Imagick $composite_object, int $composite, int $x, int $y, int $channel = Imagick::CHANNEL_DEFAULT): bool| Аргумент | Смысл, единицы и границы |
|---|---|
| $composite_object | Обязательный Imagick, отдельное непустое изображение-источник. Оно не становится возвращаемым результатом; меняется текущий объект-получатель. |
| $composite | Обязательный int-константа оператора. Здесь COMPOSITE_OVER или COMPOSITE_DSTIN; это выбор правила, не процент. Для других операторов могут понадобиться setImageArtifact("compose:args", ...), как в полном официальном примере. |
| $x / $y | Два обязательных int: столбец и строка размещения источника на получателе, в пикселях. В отличие от shadow, это реальная позиция наложения. Наш товар размещён в (20,20), а тень в(24,20). |
| $channel | Необязательный int, по умолчанию CHANNEL_DEFAULT; сочетания channel-констант задают битовой операцией |. Это не число цветов. В старой библиотеке до IM 6.2.9 channel игнорируется; в точном IM7 shim маска временно устанавливается и восстанавливается. Не обещаем, что RED сохранит остальные каналы получателя: отдельный опыт это опроверг. |
Официальная доступность: PECL imagick 2, PECL imagick 3. Публичный результат bool true; операция изменяет текущий объект, а не возвращает новый Imagick. Неверное число или тип аргументов может дать PHP-ошибку. Пустое изображение проверяется wrapper и вызывает ImagickException; пустая секция errors в XML не обещает отсутствия исключений.
Значения в программах фиксированы и умеренны. Для внешних данных отдельно ограничивают площадь полотен и число кадров, проверяют конечные неотрицательные sigma/radius, долю opacity 0..100, допустимые полуоси и whitelist операторов. Система такой валидации здесь не реализована. Издержки зависят от площади, копий и размытия; скорость или уменьшение файла не измерялись.
Полный официальный XML: описание, параметры, returns, пример и ссылки
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.compositeimage">
<refnamediv>
<refname>Imagick::compositeImage</refname>
<refpurpose>Composite one image onto another</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::compositeImage</methodname>
<methodparam><type>Imagick</type><parameter>composite_object</parameter></methodparam>
<methodparam><type>int</type><parameter>composite</parameter></methodparam>
<methodparam><type>int</type><parameter>x</parameter></methodparam>
<methodparam><type>int</type><parameter>y</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
</methodsynopsis>
<para>
Composite one image onto another at the specified offset. Any extra arguments needed for the compose algorithm should passed to setImageArtifact with 'compose:args' as the first parameter and the data as the second parameter.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>composite_object</parameter></term>
<listitem>
<para>
Imagick object which holds the composite image
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>compose</parameter></term>
<listitem>
<para>
Composite operator. See <link
linkend="imagick.constants.compositeop">Composite Operator
Constants</link>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>x</parameter></term>
<listitem>
<para>
The column offset of the composited image
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>y</parameter></term>
<listitem>
<para>
The row offset of the composited image
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>channel</parameter></term>
<listitem>
<para>
Provide any channel constant that is valid for your channel mode. To
apply to more than one channel, combine channeltype constants using
bitwise operators. Refer to this list of <link
linkend="imagick.constants.channel">channel constants</link>.
</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>Using <function>Imagick::compositeImage</function>:</title>
<para>
Composite two images with the 'mathematics' compose method
</para>
<programlisting role="php">
<![CDATA[
<?php
// Equivalent to running the command
// convert src1.png src2.png -compose mathematics -define compose:args="1,0,-0.5,0.5" -composite output.png
$src1 = new \Imagick("./src1.png");
$src2 = new \Imagick("./src2.png");
$src1->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$src1->setImageArtifact('compose:args', "1,0,-0.5,0.5");
$src1->compositeImage($src2, Imagick::COMPOSITE_MATHEMATICS, 0, 0);
$src1->writeImage("./output.png");
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>Imagick::setImageArtifact</function></member>
</simplelist>
</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
-->
Официальные HTTP-примеры сохранены целиком. Header задаёт MIME, но сам не преобразует PNG в JPEG; JPEG не хранит alpha. Наши программы сохраняют локальные PNG и не являются проверкой веб-выдачи. Основы: файлы, HTTP-ответ.
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$preview = shadowPreview($product);
$card = new Imagick();
$card->newImage(440, 360, '#e8eff4');
if (!$card->compositeImage($product, Imagick::COMPOSITE_OVER, 20, 20)) {
throw new RuntimeException('Не выполнен compositeImage');
}
$card->setImageFormat('png');
$card->setImageDepth(8);
$card->setOption('png:color-type', '2');
if (!$card->writeImage(__DIR__ . '/product-card.png')) {
throw new RuntimeException('Не записан product-card.png');
}
saveShadowComparison([$source, $preview, $card], 'composite-product.png');
$source->clear();
$preview->clear();
$card->clear();
$product->clear();
Результат: Каталог, товар на белой подложке просмотра, карточка 440×360 без тени. Готовая карточка отдельно сохранена как product-card.png; белый фон preview в этот файл не переносится. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит composite-product.png и перевод строки. Размер сравнения 1240×360: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
composite-product.png
<?php
declare(strict_types=1);
require __DIR__ . '/shadow-fixture.php';
$source = loadShadowSource();
$product = loadShadowProduct();
$mask = clone $product;
$mask->setImageAlphaChannel(Imagick::ALPHACHANNEL_EXTRACT);
$mask->setImageFormat('png');
$mask->setImageDepth(8);
$mask->setOption('png:color-type', '2');
if (!$mask->writeImage(__DIR__ . '/mask-alpha.png')) {
throw new RuntimeException('Не записан mask-alpha.png');
}
$image = clone $source;
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
if (!$image->compositeImage($product, Imagick::COMPOSITE_DSTIN, 0, 0)) {
throw new RuntimeException('Не выполнен compositeImage');
}
$image->setImageFormat('png');
$image->setImageDepth(8);
$image->setOption('png:color-type', '6');
if (!$image->writeImage(__DIR__ . '/masked-product.png')) {
throw new RuntimeException('Не записан masked-product.png');
}
$preview = shadowPreview($image);
saveShadowComparison([$source, $mask, $preview], 'composite-mask.png');
$source->clear();
$mask->clear();
$preview->clear();
$product->clear();
$image->clear();
Результат: Исходник, извлечённая alpha как серая карта, вырезанный результат на белой подложке просмотра. masked-product.png сохраняет прозрачность и отверстие ручки; mask-alpha.png показывает использованную alpha, а не RGB товара. Распакуйте example.php, shadow-fixture.php, source.png.b64 и product.png.b64 вместе. Выполните php example.php в папке с правом записи и PHP/Imagick; откройте PNG просмотрщиком. Помощник проверяет SHA256 и восстанавливает оба точных PNG без шрифтов и сети. Stdout содержит composite-mask.png и перевод строки. Размер сравнения 1200×320: панели слева направо, целиком, вертикально центрированы на белом контексте. Отдельные RGBA-файлы перечислены в пояснении; подложка просмотра не меняет их alpha.
Ожидаемый вывод
composite-mask.png
Связанный путь: модель alpha, page и размещения, границы и ошибки.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


