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

Дерево руководства
Глава 360 · После alpha и зернистой фактуры
Imagick: градиенты, опорные цвета и повтор плитки
Самостоятельные фоны и готовые карточки с предоставленным RGBA-товаром.
Сохранить карточку на собственном фоне
Нужна карточка товара, которую можно скачать, вставить в памятку или отправить одним PNG. Подложка должна быть частью файла. Начнём с мягкого градиента, затем зададим цвет по опорным точкам и добавим повторяемый орнамент. Для одного оформления веб-страницы иногда достаточно CSS; здесь сохраняется самостоятельное изображение.
RGB — красная, зелёная и синяя компоненты. RGBA добавляет alpha: 0 прозрачен, 1 непрозрачен. Есть точный собственный каталог, готовый авторский RGBA-силуэт коробки/кружки и новая прозрачная плитка 24×24. Силуэт предоставлен заранее, это не автоматическое вырезание фотографии.


Напечатанные RGB-числа, надписи и SKU — часть исходного рисунка, а не автоматические измерения нового фона. В готовой карточке SKU копируется отдельной известной областью; он не генерируется заново. Фон создаёт библиотека, готовый товар накладывается через alpha.
В этих фиксированных строках linear плавно меняет цвет по вертикали между двумя заданными цветами, radial — от центральной области к краям. Наше сравнение использует и разные формы перехода, и разные пары цветов; не приписываем всю разность одной только форме.
| Обозначение до схемы | Смысл |
|---|---|
| x, y и размеры | x растёт вправо, y вниз от левого верхнего угла. Координаты в пикселях; для размера 400×320 последние индексы 399 и 319. |
| r, g, b и Q | r/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 — минимум. Таблица первых трёх точек:
| Точка в пикселях | r | g | b |
|---|---|---|---|
| 0,0 | 0.96 | 0.98 | 1.0 |
| 399,0 | 0.72 | 0.84 | 0.92 |
| 0,319 | 0.94 | 0.86 | 0.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); уже получается другое правило, не та же плоскость.

Самая маленькая запись
$ начинает имя переменной, = присваивает результат, -> вызывает метод, аргументы в скобках разделены запятыми, ; завершает команду. 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 задаются буквальной строкой, размеры — отдельными целыми аргументами.

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

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

У программы маска RGB задана явно. Смена маски меняет и смысл, и размер каждой записи: нельзя оставить прежние x/y/r/g/b, выбрав только ALPHA. Программы и полная таблица методов: опорные точки и карточка.
Повторить прозрачный орнамент без растяжения
Орнамент нужен с постоянным размером элементов, поэтому повторяем плитку 24×24, а не растягиваем её до 400×320. На непрозрачном #e6edf1 прозрачные места плитки показывают базу. В другой практике получаем отдельный RGBA-узор на прозрачном холсте, сохраняем его и лишь потом накладываем на радиальный фон.

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-строк.
Выбрать подложку и сохранить собственный вариант

Упражнение: получить более холодный верхний правый угол 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 — минимум. Таблица первых трёх точек:
| Точка в пикселях | r | g | b |
|---|---|---|---|
| 0,0 | 0.96 | 0.98 | 1.0 |
| 399,0 | 0.72 | 0.84 | 0.92 |
| 0,319 | 0.94 | 0.86 | 0.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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


