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

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

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

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

Глава 360 · После alpha и зернистой фактуры

Imagick: градиенты, опорные цвета и повтор плитки

Самостоятельные фоны и готовые карточки с предоставленным RGBA-товаром.

Сохранить карточку на собственном фоне

Нужна карточка товара, которую можно скачать, вставить в памятку или отправить одним PNG. Подложка должна быть частью файла. Начнём с мягкого градиента, затем зададим цвет по опорным точкам и добавим повторяемый орнамент. Для одного оформления веб-страницы иногда достаточно CSS; здесь сохраняется самостоятельное изображение.

RGB — красная, зелёная и синяя компоненты. RGBA добавляет alpha: 0 прозрачен, 1 непрозрачен. Есть точный собственный каталог, готовый авторский RGBA-силуэт коробки/кружки и новая прозрачная плитка 24×24. Силуэт предоставлен заранее, это не автоматическое вырезание фотографии.

Канонический каталог 400×320. Старая надпись PNG8 означает RGB с 8 битами на компоненту, color-type 2, не индексированный PNG.
Канонический каталог 400×320. Старая надпись PNG8 означает RGB с 8 битами на компоненту, color-type 2, не индексированный PNG.
Каталог → новый градиент 400×320 → карточка с готовым RGBA-товаром и точным исходным SKU
Каталог → новый градиент 400×320 → карточка с готовым RGBA-товаром и точным исходным SKU

Напечатанные RGB-числа, надписи и SKU — часть исходного рисунка, а не автоматические измерения нового фона. В готовой карточке SKU копируется отдельной известной областью; он не генерируется заново. Фон создаёт библиотека, готовый товар накладывается через alpha.

В этих фиксированных строках linear плавно меняет цвет по вертикали между двумя заданными цветами, radial — от центральной области к краям. Наше сравнение использует и разные формы перехода, и разные пары цветов; не приписываем всю разность одной только форме.

Обозначение до схемыСмысл
x, y и размерыx растёт вправо, y вниз от левого верхнего угла. Координаты в пикселях; для размера 400×320 последние индексы 399 и 319.
r, g, b и Qr/g/b — нормированные компоненты 0..1 для sparseColorImage. Q=QuantumRange — внутренний максимум, 65535 в проверенной Q16-сборке; API sparse принимает 1 для максимума, не Q. PNG-файл хранит 0..255 на компоненту.
Точка и записьПри явной RGB-маске запись x,y,r,g,b содержит пять чисел. Это данные, не команды рисования точек. Строки PHP-массива лишь помогают видеть группы.
Период и alphaПлитка повторяется каждые 24 пикселя по обеим осям. Остатки холста 16×8 не меняют масштаб плитки. Alpha определяет вклад OVER; raw RGBA не содержит подложку просмотрщика.

Опорная точка — координаты и желаемый цвет, а не окрашенный маркер, который сам рисуется на фоне. Для RGB маски читаем группы по пять чисел: x, y, r, g, b. Здесь (0,0) — левый верхний пиксель, (399,319) — правый нижний. У 400 столбцов последний индекс 399, у 320 строк — 319. Цвета в API нормированы: 1 — максимум компоненты, 0 — минимум. Таблица первых трёх точек:

Точка в пикселяхrgb
0,00.960.981.0
399,00.720.840.92
0,3190.940.860.68

Barycentric с тремя неколлинеарными точками задаёт плоскость отдельно для каждой компоненты. t=x/399 и u=y/319 — безразмерные координаты; c00, c10, c01 — значения одной компоненты в этих трёх углах, c′ — результат: c′=c00+(c10−c00)t+(c01−c00)u. Например, в четвёртом углу получаются RGB (0.70,0.72,0.60), то есть примерно (178.5,183.6,153) в шкале файла до квантования. Это модель цвета, не геометрическое перемещение. Для Bilinear добавляем четвёртую точку (399,319,0.86,0.78,0.86); уже получается другое правило, не та же плоскость.

Фиксированная строка → фон в пустом объекте и bool; точки → изменение текущего растра и bool; холст+плитка → новый Imagick. Модели цвета и повторения не заменяют полный код.
Фиксированная строка → фон в пустом объекте и bool; точки → изменение текущего растра и bool; холст+плитка → новый Imagick. Модели цвета и повторения не заменяют полный код.

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

$ начинает имя переменной, = присваивает результат, -> вызывает метод, аргументы в скобках разделены запятыми, ; завершает команду. New Imagick() создаёт объект-инструмент. По фиксированной строке генератора создаёт фоновый растр в новом пустом объекте и возвращает bool true. Это не возврат нового Imagick из самого метода.

Одинарные кавычки создают буквальную строку: #e6edf1 и #c4d2dc — цвета #RRGGBB, где пары шестнадцатеричных цифр задают красный/зелёный/синий в шкале 0..255. Переменные внутри одинарных кавычек не подставляются. Здесь строка фиксирована автором, не получена от посетителя.

$background = new Imagick();
$background->newPseudoImage(400, 320, 'gradient:#e6edf1-#c4d2dc');

Для двух bool-методов if с ! проверяет отказ, throw new RuntimeException останавливает цепочку. У textureImage проверяем отдельный объект и пиксели результата, а не bool true. Clone делает независимую копию, простое присваивание объекта даёт ещё одно имя. Основы: объект и метод, массивы, клонирование, исключения.

Полная программа начинается с <?php и declare(strict_types=1). Require подключает background-fixture.php из __DIR__, папки программы. LoadBackgroundInput получает известное имя, восстанавливает PNG по Base64/SHA256 и возвращает Imagick. | объединяет маски RGB. GetImageSignature читает подпись пикселей для контроля неизменности входов. BackgroundCard накладывает предоставленный товар и копирует известный SKU; его код открыт ниже. [] создаёт массив полных панелей, saveBackgroundComparison сохраняет их и печатает имя файла.

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

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$background = new Imagick();
if (!$background->newPseudoImage(400, 320, 'gradient:#e6edf1-#c4d2dc')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
$background->setImageFormat('png');
$background->setImageDepth(8);
$background->setOption('png:color-type', '2');
if (!$background->writeImage(__DIR__ . '/bg-first-gradient.png')) {
    throw new RuntimeException('Не записан bg-first-gradient.png');
}
$card = backgroundCard($background, $product, $source);
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $background, $card], 'bg-first.png');
$source->clear();
$background->clear();
$card->clear();
$product->clear();
$tile->clear();

Результат: Исходный каталог; новый линейный фон 400×320; готовая карточка с предоставленным RGBA-товаром и исходным SKU. bg-first-gradient.png хранит сам фон. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — bg-first.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
bg-first.png
Полный background-fixture.php из каждого ZIP
<?php
declare(strict_types=1);

function loadBackgroundInput(string $name): Imagick
{
    $hashes = ['source' => '453b22e19273f2fdd54ec6a7f0cd9e96a7b08c70cc4cc854838d1428fea207c6', 'product' => 'f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c', 'tile' => '8c6a5f9e8cce51984cc84f8deb5da6f62a8d4d3931a03dc0bc2f048a519f586c'];
    if (!isset($hashes[$name])) { throw new InvalidArgumentException('Неизвестный вход'); }
    $encoded = file_get_contents(__DIR__ . '/' . $name . '.png.b64');
    if ($encoded === false) { throw new RuntimeException('Распакуйте весь архив'); }
    $bytes = base64_decode($encoded, true);
    if ($bytes === false || hash('sha256', $bytes) !== $hashes[$name]) { throw new RuntimeException('Повреждён входной PNG'); }
    $path = __DIR__ . '/' . $name . '.png';
    if (file_put_contents($path, $bytes) !== strlen($bytes)) { throw new RuntimeException('Не восстановлен PNG'); }
    return new Imagick($path);
}

function saveBackgroundComparison(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 backgroundCard(Imagick $background, Imagick $product, Imagick $source): Imagick
{
    $card = clone $background;
    if (!$card->compositeImage($product, Imagick::COMPOSITE_OVER, 0, 0)) { throw new RuntimeException('Не наложен товар'); }
    $sku = clone $source;
    $sku->cropImage(82, 32, 278, 48);
    $sku->setImagePage(0, 0, 0, 0);
    if (!$card->compositeImage($sku, Imagick::COMPOSITE_OVER, 278, 48)) { throw new RuntimeException('Не возвращён SKU'); }
    $sku->clear();
    return $card;
}

Function объявляет функцию, : Imagick задаёт тип результата, return возвращает его. Isset проверяет разрешённое имя, foreach перебирает панели. Base64_decode восстанавливает байты, hash проверяет SHA256, file_put_contents пишет точный вход. Помощник не вызывает newPseudo/sparse/texture для скрытой подготовки. Он клонирует фон, накладывает товар OVER и вырезает SKU 82×32 из (278,48) исходника. Для копирования области cropImage получает ширину, высоту, x, y; setImagePage сбрасывает её виртуальную позицию. Сборка alpha подробно разобрана в композиции изображений.

Выбрать генератор, опорные цвета или повтор

У генератора нужна понятная фиксированная строка и новый пустой объект. У sparse уже должен быть растр; координаты и числа цветов задают правило его заполнения. У texture нужен холст-получатель и отдельная плитка; результат присваиваем новой переменной. Эти способы решают разные требования, а не являются тремя именами одной заливки.

До следующей полной программы: $radial — пустой Imagick, $field — белый растр 400×320, $points — таблица из трёх точек выше, $canvas — непрозрачный #e6edf1. Здесь четыре панели: исходник, радиальный фон, Barycentric-поле и повтор плитки:

$radial->newPseudoImage(400, 320, 'radial-gradient:#f8efda-#7d9aa8');
$field->sparseColorImage(Imagick::SPARSECOLORMETHOD_BARYCENTRIC, $points, $rgbChannels);
$canvas->setImageCompose(Imagick::COMPOSITE_OVER);
$pattern = $canvas->textureImage($tile);
Разделить готовый генератор, опорные цвета и повтор плиткиПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$radial = new Imagick();
if (!$radial->newPseudoImage(400, 320, 'radial-gradient:#f8efda-#7d9aa8')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
$field = new Imagick();
$field->newImage(400, 320, 'white');
$points = [
    0, 0, 0.96, 0.98, 1.0,
    399, 0, 0.72, 0.84, 0.92,
    0, 319, 0.94, 0.86, 0.68,
];
if (!$field->sparseColorImage(Imagick::SPARSECOLORMETHOD_BARYCENTRIC, $points, $rgbChannels)) {
    throw new RuntimeException('Не выполнен sparseColorImage');
}
$canvas = new Imagick();
$canvas->newImage(400, 320, '#e6edf1');
$canvas->setImageCompose(Imagick::COMPOSITE_OVER);
$canvasSignature = $canvas->getImageSignature();
$pattern = $canvas->textureImage($tile);
if (!($pattern instanceof Imagick) || $pattern === $canvas || $pattern === $tile) {
    throw new RuntimeException('Нужен отдельный результат textureImage');
}
if ($canvas->getImageSignature() !== $canvasSignature) {
    throw new RuntimeException('Изменился исходный холст');
}
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $radial, $field, $pattern], 'bg-controls.png');
$source->clear();
$radial->clear();
$field->clear();
$pattern->clear();
$product->clear();
$tile->clear();
$canvas->clear();

Результат: Исходник; радиальный фон; плоскость цвета по трём точкам; новый результат повторения RGBA-плитки на непрозрачном #e6edf1. Порядок панелей именно такой. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — bg-controls.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

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

Создать фон и применить его к карточке

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

Два фиксированных фона и две готовые карточки с одним и тем же товаром: создание растра отдельно от последующего OVER
Два фиксированных фона и две готовые карточки с одним и тем же товаром: создание растра отдельно от последующего OVER

Минимальная практика создаёт самостоятельные файлы фонов. Практика карточки использует одинаковый заранее подготовленный товар и исходный SKU поверх разных подложек; товар не перекрашивается. Во всех нормальных примерах перед генератором new Imagick(), чтобы не получить лишний кадр вместо предполагаемой замены. Программы: два применения генератора.

Задать цвет в углах и собрать макет

Когда важны цвета в определённых местах, вместо строки градиента задаём координаты и нормированные компоненты. На одних и тех же трёх углах Barycentric даёт плавную плоскость цвета, Voronoi — зоны ближайших точек. Фон не распознаёт коробку/кружку и не следует их контурам.

Те же три точки: плавное Barycentric-поле и зоны Voronoi. Маркеры схемы поясняют вход, а не добавлены в PNG самой функцией.
Те же три точки: плавное Barycentric-поле и зоны Voronoi. Маркеры схемы поясняют вход, а не добавлены в PNG самой функцией.

Для четырёх разных углов используем Bilinear и четвёртую запись (399,319,0.86,0.78,0.86). Затем предоставленный RGBA-товар накладывается на готовое поле. Это развитие требования, а не утверждение, что Barycentric с четырьмя произвольными точками точно выполнит каждое пожелание.

Четырёхугольное Bilinear-поле и готовая карточка; самостоятельный sparse-field.png сохранён отдельно
Четырёхугольное Bilinear-поле и готовая карточка; самостоятельный sparse-field.png сохранён отдельно

У программы маска RGB задана явно. Смена маски меняет и смысл, и размер каждой записи: нельзя оставить прежние x/y/r/g/b, выбрав только ALPHA. Программы и полная таблица методов: опорные точки и карточка.

Повторить прозрачный орнамент без растяжения

Орнамент нужен с постоянным размером элементов, поэтому повторяем плитку 24×24, а не растягиваем её до 400×320. На непрозрачном #e6edf1 прозрачные места плитки показывают базу. В другой практике получаем отдельный RGBA-узор на прозрачном холсте, сохраняем его и лишь потом накладываем на радиальный фон.

Собственная плитка, её новый возвращённый повтор и карточка с орнаментом. Raw texture-layer.png отделён от RGB-фона texture-field.png.
Собственная плитка, её новый возвращённый повтор и карточка с орнаментом. Raw texture-layer.png отделён от RGB-фона texture-field.png.

TextureImage не меняет размер холста. Крайняя плитка частично обрезается по нему; при нулевой фазе нижний правый пиксель (399,319) соответствует (15,7) плитки. В нашей малой пробе setImagePage у плитки не сдвинул узор, а реальный roll её пикселей сдвинул; page не преподносим как универсальный регулятор фазы. Основные программы оставляют нулевую фазу и проверяют неизменность пикселей входов. Программы: повтор плитки и самостоятельный узор.

Проверить кадры, записи точек и возвращённый объект

СитуацияПричина и действие
Вместо фона ещё один кадрNewPseudoImage идёт через reader и может добавить кадр. Создавайте новый пустой объект для каждого фона; количество и текущий кадр проверены отдельно.
В строке остались $colour1 и $colour2Одинарные кавычки не подставляют переменные. Начните с фиксированных проверенных цветов; сборка строк и их валидация — отдельный шаг.
Sparse не принял массивПроверьте число элементов в группе выбранных активных каналов и геометрию точек. Координаты в пикселях, компоненты 0..1, не 255/Q.
Нет ожидаемой прозрачностиAlpha — отдельный канал и должна быть активна. Ни яркий RGB, ни COPY автоматически не гарантируют правильную alpha. Main-фоны непрозрачны, raw орнамент отдельно RGBA.
Texture будто не сработалСохраните возвращённый новый Imagick. Не продолжайте записывать старый $canvas, не ожидайте bool true.
Ожидалось покрытие фотографией без повторовTile — повтор; cover — масштабирование с обрезкой. Эти программы не выполняют cover и не маскируют эту разницу.

Подпись пикселей проверяется до/после реальной работы; это не гарантия неизменности всех metadata. Сохранённые PNG и независимые проверки опорных формул/повтора/OVER подтверждают именно эти входы и настройки. В supplied RGBA-товаре alpha подготовлена автором, а не найдена из RGB-фотографии. Статические надписи исходника сами не обновляются.

Все полные raw XML, включая шесть примеров sparse и plasma у генератора, сохранены ниже карточек. Другие методы/исторические узлы остаются в полном объёме руководства. Здесь проверена локальная запись PNG; нет обещаний HTTP-выдачи, совпадения с CSS, цветопробной печати, скорости или универсальной безопасности внешних файлов/reader-строк.

Выбрать подложку и сохранить собственный вариант

Два цвета → фиксированный генератор; цвета в координатах → sparse; постоянный маленький мотив → texture; готовый RGBA-товар накладывается отдельным шагом
Два цвета → фиксированный генератор; цвета в координатах → sparse; постоянный маленький мотив → texture; готовый RGBA-товар накладывается отдельным шагом

Упражнение: получить более холодный верхний правый угол Bilinear-карточки. Решение: изменить только нормированный RGB второй записи, сохранив её (399,0), пять чисел на точку и RGB-маску. Например, уменьшить r с 0.72 до 0.62. Выполните изменённую программу и проверьте угол и неизменный SKU; сохранённые свидетельства относятся к исходным восьми определениям.

Соседние задачи: зернистая фактура, тень и alpha-композиция, палитра и lookup, математика компонент. Сначала определите, создаёте ли новую подложку, меняете ли цвет существующего изображения или собираете отдельные слои.

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

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

Imagick::newPseudoImageПо фиксированной строке генератора создаёт фоновый растр в новом пустом объекте и возвращает bool true. Это не возврат нового Imagick из самого метода.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::newPseudoImage(int $columns, int $rows, string $pseudoString): bool

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

$ начинает имя переменной, = присваивает результат, -> вызывает метод, аргументы в скобках разделены запятыми, ; завершает команду. New Imagick() создаёт объект-инструмент. По фиксированной строке генератора создаёт фоновый растр в новом пустом объекте и возвращает bool true. Это не возврат нового Imagick из самого метода.

Одинарные кавычки создают буквальную строку: #e6edf1 и #c4d2dc — цвета #RRGGBB, где пары шестнадцатеричных цифр задают красный/зелёный/синий в шкале 0..255. Переменные внутри одинарных кавычек не подставляются. Здесь строка фиксирована автором, не получена от посетителя.

$background = new Imagick();
$background->newPseudoImage(400, 320, 'gradient:#e6edf1-#c4d2dc');

Для двух bool-методов if с ! проверяет отказ, throw new RuntimeException останавливает цепочку. У textureImage проверяем отдельный объект и пиксели результата, а не bool true. Clone делает независимую копию, простое присваивание объекта даёт ещё одно имя. Основы: объект и метод, массивы, клонирование, исключения.

Полная официальная сигнатура

Imagick::newPseudoImage(int $columns, int $rows, string $pseudoString): bool
АргументЕдиницы и ограничения
$columnsОбязательный int — ширина в пикселях, здесь 400.
$rowsОбязательный int — высота в пикселях, здесь 320. Нулевые размеры в 3.8.1 могут дать deprecation; для внешних данных нужны положительные ограниченные размеры.
$pseudoStringОбязательная строка с именем формата и определением, например gradient:#e6edf1-#c4d2dc. Двоеточие отделяет генератор, дефис разделяет цвета. Проверка наличия : в wrapper не является whitelist безопасных строк; дальше используется общий reader ImageMagick.

Официальная доступность: PECL imagick 2, PECL imagick 3. Официальный результат: Returns true on success.

Примеры используют позиционные аргументы. Официальные имена параметров сохранены; в проверенной 3.8.1 Reflection для named arguments даёт pseudo_format у newPseudoImage, sparsecolormethod у sparseColorImage и texture у textureImage. Не заменяйте ими raw-сигнатуру молча.

На непустом объекте общий reader может ДОБАВИТЬ кадр в последовательность: в нашей малой проверке количество стало 2, первый кадр сохранился, текущим стал новый фон. Это не обещание заменить исходный bitmap. Обычные программы создают новый пустой Imagick перед каждым фоном. Отсутствие : и неизвестная фиксированная строка дали ImagickException; одной : недостаточно для безопасности. Разные генераторы/форматы зависят от версии, policy, delegates или шрифта; здесь только проверенные gradient/radial-gradient без сети и шрифтов. Raw plasma:fractal сохраняем, но не выдаём за детерминированный цветовой фон.

Для записи результата отдельно задаём PNG и проверяем writeImage. Основные сравнения — RGB с 8 битами на компоненту, color-type 2; RGBA-узор — color-type 6. Это не индексированная палитра и не доказательство печатной цветопередачи. Крупные размеры и промежуточные копии требуют памяти; время здесь не измерялось. Не передавайте произвольные размеры, пути или reader-строки без отдельной прикладной проверки.

Полный исходный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.newpseudoimage">
 <refnamediv>
  <refname>Imagick::newPseudoImage</refname>
  <refpurpose>Creates a new image</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::newPseudoImage</methodname>
   <methodparam><type>int</type><parameter>columns</parameter></methodparam>
   <methodparam><type>int</type><parameter>rows</parameter></methodparam>
   <methodparam><type>string</type><parameter>pseudoString</parameter></methodparam>
  </methodsynopsis>
  <para>
   Creates a new image using ImageMagick pseudo-formats.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>columns</parameter></term>
     <listitem>
      <para>
       columns in the new image
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>rows</parameter></term>
     <listitem>
      <para>
       rows in the new image
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>pseudoString</parameter></term>
     <listitem>
      <para>
       string containing pseudo image definition.
      </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="examples">
  &reftitle.examples;
  <para>
    <example>
      <title> <function>Imagick::newPseudoImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
function newPseudoImage($canvasType) {
    $imagick = new \Imagick();
    $imagick->newPseudoImage(300, 300, $canvasType);
    $imagick->setImageFormat("png");
    header("Content-Type: image/png");
    echo $imagick->getImageBlob();
}

//newPseudoImage('gradient:red-rgba(64, 255, 255, 0.5)');
//newPseudoImage("radial-gradient:red-blue");
newPseudoImage("plasma:fractal");

?>
]]>
      </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
-->

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

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$linear = new Imagick();
if (!$linear->newPseudoImage(400, 320, 'gradient:#e6edf1-#c4d2dc')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
$radial = new Imagick();
if (!$radial->newPseudoImage(400, 320, 'radial-gradient:#f8efda-#7d9aa8')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $linear, $radial], 'pseudo-backgrounds.png');
$source->clear();
$linear->clear();
$radial->clear();
$product->clear();
$tile->clear();

Результат: Исходник и два независимо созданных фона одинакового размера. Каждый newPseudoImage вызывается на новом пустом Imagick; это не замена кадра через clone исходника. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — pseudo-backgrounds.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

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

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$linear = new Imagick();
if (!$linear->newPseudoImage(400, 320, 'gradient:#e6edf1-#c4d2dc')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
$radial = new Imagick();
if (!$radial->newPseudoImage(400, 320, 'radial-gradient:#f8efda-#7d9aa8')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
$linearCard = backgroundCard($linear, $product, $source);
$radialCard = backgroundCard($radial, $product, $source);
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $linearCard, $radialCard], 'pseudo-cards.png');
$source->clear();
$linearCard->clear();
$radialCard->clear();
$product->clear();
$tile->clear();
$linear->clear();
$radial->clear();

Результат: Исходный каталог; товар+SKU на линейном фоне; тот же товар+SKU на радиальном. Прозрачный силуэт поставляется как вход, не вырезается из фотографии автоматически. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — pseudo-cards.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
pseudo-cards.png
Imagick::sparseColorImageРаспространяет значения компонентов, заданные в нескольких координатах, по текущему растру. Метод задаёт правило интерполяции или выбора ближайшей точки; результатом вызова является bool true.

PECL imagick 2 >= 2.3.0, PECL imagick 3 · imagick

Imagick::sparseColorImage(int $SPARSE_METHOD, array $arguments, int $channel = Imagick::CHANNEL_DEFAULT): bool

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

$ начинает имя переменной, = присваивает результат, -> вызывает метод, аргументы в скобках разделены запятыми, ; завершает команду. New Imagick() создаёт объект-инструмент. Распространяет значения компонентов, заданные в нескольких координатах, по текущему растру. Метод задаёт правило интерполяции или выбора ближайшей точки; результатом вызова является bool true.

Опорная точка — координаты и желаемый цвет, а не окрашенный маркер, который сам рисуется на фоне. Для RGB маски читаем группы по пять чисел: x, y, r, g, b. Здесь (0,0) — левый верхний пиксель, (399,319) — правый нижний. У 400 столбцов последний индекс 399, у 320 строк — 319. Цвета в API нормированы: 1 — максимум компоненты, 0 — минимум. Таблица первых трёх точек:

Точка в пикселяхrgb
0,00.960.981.0
399,00.720.840.92
0,3190.940.860.68

Barycentric с тремя неколлинеарными точками задаёт плоскость отдельно для каждой компоненты. t=x/399 и u=y/319 — безразмерные координаты; c00, c10, c01 — значения одной компоненты в этих трёх углах, c′ — результат: c′=c00+(c10−c00)t+(c01−c00)u. Например, в четвёртом углу получаются RGB (0.70,0.72,0.60), то есть примерно (178.5,183.6,153) в шкале файла до квантования. Это модель цвета, не геометрическое перемещение. Для Bilinear добавляем четвёртую точку (399,319,0.86,0.78,0.86); уже получается другое правило, не та же плоскость.

Квадратные скобки [] создают плоский массив; переносы строк помогают видеть группы, запятые отделяют числа. Imagick::ИМЯ — константа класса; :: соединяет имя класса и константу, | объединяет маски RGB. Сначала создаём непустой белый растр:

$field = new Imagick();
$field->newImage(400, 320, 'white');
$points = [
    0, 0, 0.96, 0.98, 1.0,
    399, 0, 0.72, 0.84, 0.92,
    0, 319, 0.94, 0.86, 0.68,
];
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$field->sparseColorImage(Imagick::SPARSECOLORMETHOD_BARYCENTRIC, $points, $rgbChannels);

Для двух bool-методов if с ! проверяет отказ, throw new RuntimeException останавливает цепочку. У textureImage проверяем отдельный объект и пиксели результата, а не bool true. Clone делает независимую копию, простое присваивание объекта даёт ещё одно имя. Основы: объект и метод, массивы, клонирование, исключения.

Полная официальная сигнатура

Imagick::sparseColorImage(int $SPARSE_METHOD, array $arguments, int $channel = Imagick::CHANNEL_DEFAULT): bool
АргументЕдиницы и ограничения
$SPARSE_METHODОбязательная int-константа SPARSECOLORMETHOD_*. Основные программы показывают BARYCENTRIC, VORONOI и BILINEAR. Число точек и поведение зависят от выбранного метода.
$argumentsОбязательный плоский массив. При явной RGB-маске одна запись: x,y,r,g,b. Координаты в пикселях, цвета нормированы в 0..1; не передавайте 255 или Q вместо 1. При активной alpha и её выборе добавляется A, для CMYK возможен K. Размер записи зависит от реально выбранных активных каналов.
$channelНеобязательная int-маска CHANNEL_DEFAULT. В примерах явно RED | GREEN | BLUE; | объединяет разрешения изменять компоненты. Это даёт пять чисел на RGB-точку даже на RGBA. RED-only использует x,y,r, активный default RGBA — обычно x,y,r,g,b,a.

Официальная доступность: PECL imagick 2 >= 2.3.0, PECL imagick 3. Официальный результат: Returns true on success.

Примеры используют позиционные аргументы. Официальные имена параметров сохранены; в проверенной 3.8.1 Reflection для named arguments даёт pseudo_format у newPseudoImage, sparsecolormethod у sparseColorImage и texture у textureImage. Не заменяйте ими raw-сигнатуру молча.

Требуется IM 6.4.5 или новее. Raw краткая запись массива и его общий helper сохранены целиком. Helper raw добавляет RGBA, но для непрозрачного RGB-холста запись по умолчанию может иметь другой размер; не копируйте её, не согласовав активные каналы. В наших программах ровно x,y,r,g,b при явной RGB-маске. В проверке RED использовал 3 числа, активный RGBA — 6; цвета умножает на Q сама библиотека. Q=QuantumRange, в нашей Q16-сборке 65535, это не шкала входных нормированных цветов.

МетодМодель и граница
BARYCENTRICОдна точка — постоянный цвет; две используют дополнительное направление; три неколлинеарные задают плоскость. Более трёх — подбор по наименьшим квадратам, а не гарантия точного прохождения через все цвета.
BILINEARЧетыре пригодных опорных точки задают билинейное правило; при меньшем числе Core может перейти к аффинному. Основной пример использует четыре угла.
POLYNOMIALВ начале массива стоит порядок полинома, затем точки; требуемое число зависит от порядка. Это отдельный формат, не тот же список без ведущего значения.
SPEPARDS / INVERSEВзвешивание расстояниями. SPEPARDS — фактическое написание PHP-константы, хотя алгоритм называют Shepard. Ограничение весов означает, что нельзя обещать точный цвет точки для любых конфигураций.
VORONOI / MANHATTANВыбор ближайшей точки; отличаются метрикой расстояния. Зоны цвета не являются распознаванием предметов. Доступность констант зависит от версии.

Неверный размер группы и коллинеарные точки в нашей пробе дали ImagickException. Внешние массивы отдельно проверяют на числовые конечные значения и пригодную геометрию: helper обёртки приводит значения к double, поэтому не обещаем автоматический отказ каждого нечислового элемента. Значения результата ограничиваются внутренним диапазоном, возможны цветовые сдвиги/квантование.

Для записи результата отдельно задаём PNG и проверяем writeImage. Основные сравнения — RGB с 8 битами на компоненту, color-type 2; RGBA-узор — color-type 6. Это не индексированная палитра и не доказательство печатной цветопередачи. Крупные размеры и промежуточные копии требуют памяти; время здесь не измерялось. Не передавайте произвольные размеры, пути или reader-строки без отдельной прикладной проверки.

Полный исходный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->

<refentry xml:id="imagick.sparsecolorimage" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
 <refnamediv>
  <refname>Imagick::sparseColorImage</refname>
  <refpurpose>Interpolates colors</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::sparseColorImage</methodname>
   <methodparam><type>int</type><parameter>SPARSE_METHOD</parameter></methodparam>
   <methodparam><type>array</type><parameter>arguments</parameter></methodparam>
   <methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
  </methodsynopsis>
  <para>
   Given the arguments array containing numeric values this method interpolates
   the colors found at those coordinates across the whole image using <parameter>sparse_method</parameter>.
   &imagick.method.available.0x645;
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>SPARSE_METHOD</parameter></term>
     <listitem>
      <para>
       Refer to this list of <link linkend="imagick.constants.sparsecolormethod">sparse method constants</link>
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>arguments</parameter></term>
     <listitem>
      <para>
       An array containing the coordinates. 
       The array is in format <literal>array(1,1, 2,45)</literal>
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>channel</parameter></term>
     <listitem>
      <para>
       &imagick.parameter.channel;
      </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="examples">
  &reftitle.examples;
  <para>
    <example>
      <title>SPARSECOLORMETHOD_BARYCENTRIC <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
    function renderImageBarycentric2() {
        $points = [
            [0.30, 0.10, 'red'],
            [0.10, 0.80, 'blue'],
            [0.70, 0.60, 'lime'],
            [0.80, 0.20, 'yellow'],
        ];
        $imagick = createGradientImage(
            400, 400,
            $points,
            \Imagick::SPARSECOLORMETHOD_BARYCENTRIC
        );
        header("Content-Type: image/png");
        echo $imagick->getImageBlob();
    }

?>
]]>
      </programlisting>
    </example>

    <example>
      <title>SPARSECOLORMETHOD_BILINEAR <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
    function renderImageBilinear() {
        $points = [[0.30, 0.10, 'red'], [0.10, 0.80, 'blue'], [0.70, 0.60, 'lime'], [0.80, 0.20, 'yellow'],];
        $imagick = createGradientImage(500, 500, $points, \Imagick::SPARSECOLORMETHOD_BILINEAR);
        header("Content-Type: image/png");
        echo $imagick->getImageBlob();
    }

?>
]]>
      </programlisting>
    </example>

    <example>
      <title>SPARSECOLORMETHOD_SPEPARDS <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
    function renderImageShepards() {
        $points = [
            [0.30, 0.10, 'red'],
            [0.10, 0.80, 'blue'],
            [0.70, 0.60, 'lime'],
            [0.80, 0.20, 'yellow'],
        ];
        $imagick = createGradientImage(600, 600, $points, \Imagick::SPARSECOLORMETHOD_SPEPARDS);
        header("Content-Type: image/png");
        echo $imagick->getImageBlob();
    }

?>
]]>
      </programlisting>
    </example>

    <example>
      <title>SPARSECOLORMETHOD_VORONOI <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
    function renderImageVoronoi() {
        $points = [
            [0.30, 0.10, 'red'],
            [0.10, 0.80, 'blue'],
            [0.70, 0.60, 'lime'],
            [0.80, 0.20, 'yellow'],
        ];
        $imagick = createGradientImage(500, 500, $points, \Imagick::SPARSECOLORMETHOD_VORONOI);
        header("Content-Type: image/png");
        echo $imagick->getImageBlob();
    }

?>
]]>
      </programlisting>
    </example>

    <example>
      <title>SPARSECOLORMETHOD_BARYCENTRIC <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
    function renderImageBarycentric() {
        $points = [
            [0, 0, 'skyblue'],
            [-1, 1, 'skyblue'],
            [1, 1, 'black'],
        ];
        $imagick = createGradientImage(600, 200, $points, \Imagick::SPARSECOLORMETHOD_BARYCENTRIC);
        header("Content-Type: image/png");
        echo $imagick->getImageBlob();
    }

?>
]]>
      </programlisting>
    </example>

    <example>
      <title>createGradientImage is used by other examples. <function>Imagick::sparseColorImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
function createGradientImage($width, $height, $colorPoints, $sparseMethod, $absolute = false) {

    $imagick = new \Imagick();
    $imagick->newImage($width, $height, "white");
    $imagick->setImageFormat("png");

    $barycentricPoints = array();

    foreach ($colorPoints as $colorPoint) {

        if ($absolute == true) {
            $barycentricPoints[] = $colorPoint[0];
            $barycentricPoints[] = $colorPoint[1];
        }
        else {
            $barycentricPoints[] = $colorPoint[0] * $width;
            $barycentricPoints[] = $colorPoint[1] * $height;
        }

        if (is_string($colorPoint[2])) {
            $imagickPixel = new \ImagickPixel($colorPoint[2]);
        }
        else if ($colorPoint[2] instanceof \ImagickPixel) {
            $imagickPixel = $colorPoint[2];
        }
        else{
            $errorMessage = sprintf(
                "Value %s is neither a string nor an ImagickPixel class. Cannot use as a color.",
                $colorPoint[2]
            );

            throw new \InvalidArgumentException(
                $errorMessage
            );
        }

        $red = $imagickPixel->getColorValue(\Imagick::COLOR_RED);
        $green = $imagickPixel->getColorValue(\Imagick::COLOR_GREEN);
        $blue = $imagickPixel->getColorValue(\Imagick::COLOR_BLUE);
        $alpha = $imagickPixel->getColorValue(\Imagick::COLOR_ALPHA);

        $barycentricPoints[] = $red;
        $barycentricPoints[] = $green;
        $barycentricPoints[] = $blue;
        $barycentricPoints[] = $alpha;
    }

    $imagick->sparseColorImage($sparseMethod, $barycentricPoints);

    return $imagick;
}

?>
]]>
      </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
-->
Сравнить плавное поле и цветовые зоны по тем же точкамПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$field = new Imagick();
$field->newImage(400, 320, 'white');
$points = [
    0, 0, 0.96, 0.98, 1.0,
    399, 0, 0.72, 0.84, 0.92,
    0, 319, 0.94, 0.86, 0.68,
];
if (!$field->sparseColorImage(Imagick::SPARSECOLORMETHOD_BARYCENTRIC, $points, $rgbChannels)) {
    throw new RuntimeException('Не выполнен sparseColorImage');
}
$zones = new Imagick();
$zones->newImage(400, 320, 'white');
$points = [
    0, 0, 0.96, 0.98, 1.0,
    399, 0, 0.72, 0.84, 0.92,
    0, 319, 0.94, 0.86, 0.68,
];
if (!$zones->sparseColorImage(Imagick::SPARSECOLORMETHOD_VORONOI, $points, $rgbChannels)) {
    throw new RuntimeException('Не выполнен sparseColorImage');
}
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $field, $zones], 'sparse-methods.png');
$source->clear();
$field->clear();
$zones->clear();
$product->clear();
$tile->clear();

Результат: Исходник; Barycentric по трём неколлинеарным опорным точкам; Voronoi по тем же трём цветам и координатам. Смешивание и выбор ближайшей точки дают разные оформления. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — sparse-methods.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
sparse-methods.png
Собрать карточку на четырёхугольном цветовом полеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$field = new Imagick();
$field->newImage(400, 320, 'white');
$points = [
    0, 0, 0.96, 0.98, 1.0,
    399, 0, 0.72, 0.84, 0.92,
    0, 319, 0.94, 0.86, 0.68,
    399, 319, 0.86, 0.78, 0.86,
];
if (!$field->sparseColorImage(Imagick::SPARSECOLORMETHOD_BILINEAR, $points, $rgbChannels)) {
    throw new RuntimeException('Не выполнен sparseColorImage');
}
$field->setImageFormat('png');
$field->setImageDepth(8);
$field->setOption('png:color-type', '2');
if (!$field->writeImage(__DIR__ . '/sparse-field.png')) {
    throw new RuntimeException('Не записан sparse-field.png');
}
$card = backgroundCard($field, $product, $source);
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $field, $card], 'sparse-card.png');
$source->clear();
$field->clear();
$card->clear();
$product->clear();
$tile->clear();

Результат: Исходник; Bilinear-поле по четырём углам; товар+SKU на нём. sparse-field.png хранит самостоятельный фон. Пиксели SKU возвращены из исходного каталога без перекрашивания. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — sparse-card.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
sparse-card.png
Imagick::textureImageБерёт размер и свойства получателя, повторяет на его копии другое изображение-плитку и ВОЗВРАЩАЕТ НОВЫЙ Imagick. Оба входных объекта в наших проверках сохраняют свои пиксели.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::textureImage(Imagick $texture_wand): Imagick

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

$ начинает имя переменной, = присваивает результат, -> вызывает метод, аргументы в скобках разделены запятыми, ; завершает команду. New Imagick() создаёт объект-инструмент. Берёт размер и свойства получателя, повторяет на его копии другое изображение-плитку и ВОЗВРАЩАЕТ НОВЫЙ Imagick. Оба входных объекта в наших проверках сохраняют свои пиксели.

В $tile уже загружен PNG-плитка. COMPOSITE_OVER означает наложение с учётом alpha; задаётся у получателя. Справа после = стоит вызов, который возвращает новый объект; $pattern сохраняет именно его. Слово texture здесь не означает масштабирование картинки под размер фона.

$canvas = new Imagick();
$canvas->newImage(400, 320, '#e6edf1');
$canvas->setImageCompose(Imagick::COMPOSITE_OVER);
$pattern = $canvas->textureImage($tile);

Для двух bool-методов if с ! проверяет отказ, throw new RuntimeException останавливает цепочку. У textureImage проверяем отдельный объект и пиксели результата, а не bool true. Clone делает независимую копию, простое присваивание объекта даёт ещё одно имя. Основы: объект и метод, массивы, клонирование, исключения.

Полная официальная сигнатура

Imagick::textureImage(Imagick $texture_wand): Imagick
АргументЕдиницы и ограничения
$texture_wandОбязательный непустой Imagick с плиткой. Это не имя файла и не цвет. Размеры плитки определяют период повтора; размер получателя задаёт размер результата. Новое изображение нужно присвоить переменной.

Официальная доступность: PECL imagick 2, PECL imagick 3. Официальный результат: Returns a new Imagick object that has the repeated texture applied.

Примеры используют позиционные аргументы. Официальные имена параметров сохранены; в проверенной 3.8.1 Reflection для named arguments даёт pseudo_format у newPseudoImage, sparsecolormethod у sparseColorImage и texture у textureImage. Не заменяйте ими raw-сигнатуру молча.

Получатель и плитка должны быть непустыми; пустые дали ImagickException. Wrapper создаёт новый PHP-объект из возвращённого Wand. Core клонирует плитку, переводит её в пространство цвета получателя и использует compose получателя. Поэтому произвольный RGBA/CMYK/compose не равен простому byte-copy. В наших opaque/transparent OVER-контролях входные пиксели сохранились. При COPY на непрозрачном холсте проверка оставила alpha непрозрачной: не обещаем, что COPY переносит всякую alpha без подготовки. Размеры получателя сохраняются, лишняя часть крайней плитки отсекается, не растягивается.

Для записи результата отдельно задаём PNG и проверяем writeImage. Основные сравнения — RGB с 8 битами на компоненту, color-type 2; RGBA-узор — color-type 6. Это не индексированная палитра и не доказательство печатной цветопередачи. Крупные размеры и промежуточные копии требуют памяти; время здесь не измерялось. Не передавайте произвольные размеры, пути или reader-строки без отдельной прикладной проверки.

Полный исходный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.textureimage">
 <refnamediv>
  <refname>Imagick::textureImage</refname>
  <refpurpose>Repeatedly tiles the texture image</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>

   <type>Imagick</type><methodname>Imagick::textureImage</methodname>
   <methodparam><type>Imagick</type><parameter>texture_wand</parameter></methodparam>
  </methodsynopsis>
  <para>
   Repeatedly tiles the texture image across and down the image canvas.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>texture_wand</parameter></term>
     <listitem>
      <para>
       Imagick object to use as texture image
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns a new Imagick object that has the repeated texture applied.
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>



 <refsect1 role="examples">
  &reftitle.examples;
  <para>
    <example>
      <title> <function>Imagick::textureImage</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
function textureImage($imagePath) {
    $image = new \Imagick();
    $image->newImage(640, 480, new \ImagickPixel('pink'));
    $image->setImageFormat("jpg");
    $texture = new \Imagick(realpath($imagePath));
    $texture->scaleimage($image->getimagewidth() / 4, $image->getimageheight() / 4);
    $image = $image->textureImage($texture);
    header("Content-Type: image/jpg");
    echo $image;
}

?>
]]>
      </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
-->
Повторить собственную прозрачную плитку на светлой подложкеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$canvas = new Imagick();
$canvas->newImage(400, 320, '#e6edf1');
$canvas->setImageCompose(Imagick::COMPOSITE_OVER);
$canvasSignature = $canvas->getImageSignature();
$pattern = $canvas->textureImage($tile);
if (!($pattern instanceof Imagick) || $pattern === $canvas || $pattern === $tile) {
    throw new RuntimeException('Нужен отдельный результат textureImage');
}
if ($canvas->getImageSignature() !== $canvasSignature) {
    throw new RuntimeException('Изменился исходный холст');
}
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $pattern], 'texture-repeat.png');
$source->clear();
$pattern->clear();
$product->clear();
$tile->clear();
$canvas->clear();

Результат: Исходный каталог и новый Imagick с плиткой 24×24, повторённой на #e6edf1. Холст имеет 400×320; справа остаются 16 столбцов очередной плитки, снизу 8 строк. Плитка не растягивается. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — texture-repeat.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
texture-repeat.png
Сохранить отдельный узор и карточку с орнаментомПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/background-fixture.php';
$source = loadBackgroundInput('source');
$product = loadBackgroundInput('product');
$tile = loadBackgroundInput('tile');
$sourceSignature = $source->getImageSignature();
$productSignature = $product->getImageSignature();
$tileSignature = $tile->getImageSignature();
$rgbChannels = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
$canvas = new Imagick();
$canvas->newImage(400, 320, 'transparent');
$canvas->setImageCompose(Imagick::COMPOSITE_OVER);
$canvasSignature = $canvas->getImageSignature();
$layer = $canvas->textureImage($tile);
if (!($layer instanceof Imagick) || $layer === $canvas || $layer === $tile) {
    throw new RuntimeException('Нужен отдельный результат textureImage');
}
if ($canvas->getImageSignature() !== $canvasSignature) {
    throw new RuntimeException('Изменился исходный холст');
}
$layer->setImageFormat('png');
$layer->setImageDepth(8);
$layer->setOption('png:color-type', '6');
if (!$layer->writeImage(__DIR__ . '/texture-layer.png')) {
    throw new RuntimeException('Не записан texture-layer.png');
}
$background = new Imagick();
if (!$background->newPseudoImage(400, 320, 'radial-gradient:#f8efda-#7d9aa8')) {
    throw new RuntimeException('Не выполнен newPseudoImage');
}
if (!$background->compositeImage($layer, Imagick::COMPOSITE_OVER, 0, 0)) {
    throw new RuntimeException('Не выполнен compositeImage');
}
$background->setImageFormat('png');
$background->setImageDepth(8);
$background->setOption('png:color-type', '2');
if (!$background->writeImage(__DIR__ . '/texture-field.png')) {
    throw new RuntimeException('Не записан texture-field.png');
}
$card = backgroundCard($background, $product, $source);
if ($source->getImageSignature() !== $sourceSignature || $product->getImageSignature() !== $productSignature || $tile->getImageSignature() !== $tileSignature) {
    throw new RuntimeException('Изменились исходные пиксели');
}
saveBackgroundComparison([$source, $background, $card], 'texture-card.png');
$source->clear();
$background->clear();
$card->clear();
$product->clear();
$tile->clear();
$canvas->clear();
$layer->clear();

Результат: Исходник; орнамент OVER радиального фона; готовая карточка с товаром и точным SKU. texture-layer.png — самостоятельный RGBA-узор без фона просмотра, texture-field.png — фон после его композиции. Распакуйте архив целиком. Для запуска нужны example.php, background-fixture.php и три файла source.png.b64/product.png.b64/tile.png.b64 рядом. Выполните php example.php с Imagick и правом записи. Все три точных PNG восстанавливаются помощником по Base64/SHA256 во всех восьми программах, без сети/шрифтов. Stdout — texture-card.png и перевод строки. Полные панели 400×320 идут слева направо, без изменения масштаба. Отдельные файлы RGBA не содержат белого фона просмотрщика.

Ожидаемый вывод
texture-card.png
Источники и обсуждения

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

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

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

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