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

Дерево руководства
Глава 339 · После первых фигур
ImagickDraw: сохранить рисунок, воспроизвести шаблон и не потерять команды
Один понятный значок — сохранённый снимок, новый Draw и настоящий PNG. Разбираем reset, viewbox, невидимые комментарии и реальный отказ render с рабочим drawImage.
Один раз описать значок и снова получить готовый PNG
В сервисе выдачи заказов нужен понятный значок подтверждения: бирюзовая карточка, три мятные строки и золотистый круг с белой галочкой. Этот же значок понадобится фоновому заданию. Вместо повторения всей геометрии сохраним собственную очередь как строку и восстановим её в другом объекте.

ImagickDraw — объект с записанными командами, например «прямоугольник от этих координат до этих». Imagick — отдельный объект изображения с настоящими пикселями. $saved — переменная со строкой снимка; знак = сохраняет результат вызова. new создаёт отдельный объект, -> вызывает его метод, скобки содержат аргументы, точка с запятой завершает инструкцию. Начальные понятия доступны в переменных и объектах; текущую связь команд и пикселей разберём здесь.
Сначала выделим четыре строки нового действия. Это поясняющая выдержка, а не отдельная программа: $draw уже содержит наши фигуры, а $image уже создан как холст. Полный запускаемый исходник с их созданием находится сразу ниже.
$saved = $draw->getVectorGraphics();
$replay = new ImagickDraw();
$replay->setVectorGraphics($saved);
$image->drawImage($replay);Первая строка получает строковый снимок, вторая создаёт независимый Draw, третья импортирует туда снимок, четвёртая исполняет его на настоящих пикселях. При сохранении PNG дальше используется отдельный writeImage. Ни getter, ни setter сами не создают файл.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->roundRectangle(30, 30, 300, 170, 18, 18);
$draw->setFillColor('#ffe08a');
$draw->circle(245, 100, 280, 100);
$draw->setFillColor('none');
$draw->setStrokeColor('white');
$draw->setStrokeWidth(8);
$draw->polyline([['x' => 226, 'y' => 100], ['x' => 240, 'y' => 114], ['x' => 264, 'y' => 86]]);
$draw->setStrokeColor('none');
$draw->setFillColor('#bdebe2');
$draw->rectangle(55, 62, 175, 76);
$draw->rectangle(55, 95, 145, 109);
$draw->rectangle(55, 128, 165, 142);
$saved = $draw->getVectorGraphics();
$replay = new ImagickDraw();
if (!$replay->setVectorGraphics($saved)) {
throw new RuntimeException('Не удалось восстановить свой рисунок');
}
$image->drawImage($replay);
$draw->clear();
$replay->clear();
$path = __DIR__ . '/first-replayed-parcel.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'first-replayed-parcel.png', "\n";
$image->clear();
Результат: first-replayed-parcel.png 360×200. Золотистый круг с белой галочкой находится справа, три мятные строки слева. GetVectorGraphics получает строку, setVectorGraphics переносит её в новый Draw, drawImage исполняет его на $image, writeImage сохраняет файл. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Фигуры используют координаты x вправо, y вниз. Rectangle получает две противоположные вершины, circle — центр и точку на окружности; polyline получает список вершин белой галочки. Fill — заливка, stroke — линия контура, none отключает соответствующую краску. Эти операции последовательно записываются и затем выполняются; подробности — первые фигуры.
Что находится в строке, а что — в PNG

| Что у нас есть | Как используем | Чего ещё нет |
|---|---|---|
| Очередь Draw | Записываем цвета, координаты и команды | Готового PNG и внешнего холста внутри вызова setter. |
| Строка DrawingWand XML | Сохраняем свой снимок и передаём парному setter | Стандартного SVG для браузера и упакованных внешних ресурсов. |
| Imagick с пикселями | Исполняем drawImage и сохраняем writeImage | Обратного восстановления исходных команд из произвольного PNG. |
Аналогия: Draw похож на лист с инструкциями маляру, а PNG — уже окрашенная поверхность. Это модель порядка действий, а не устройство памяти. Из готовых пикселей getter не извлекает прежние круги/прямоугольники. Снимок содержит XML-оболочку и внутри MVG, язык команд ImageMagick; это другой формат, чем SVG с тегами rect/circle.
Хранить свой снимок и не перепутать формат

Для файла используют file_put_contents и file_get_contents: первая записывает байты и возвращает их число либо false, вторая читает строку либо false. Сравнение !== проверяет и значение, и тип. Снимок можно хранить рядом с исходниками, но он не заменяет исходный PHP-код и не является обещанием совместимости всех версий. На текущем runtime результат getter уже начинается с drawing-wand; старое оборачивание в root из официального примера здесь не используется, потому что оно привело к отказу drawImage в отдельной проверке.
Приложенный parcel.xml — наш короткий фиксированный шаблон без шрифтов, внешних изображений и ссылок на файлы. Проверяем размер и SHA-256 известных байтов до исполнения. Это удобный договор поставки конкретного шаблона, а не попытка разрешить загрузку произвольного SVG/MVG посетителям. При изменении содержимого утверждённого шаблона меняется и ожидаемый хеш. Подробнее — чтение и запись файлов, исключения.
Назначить холст и масштаб явно

Холст — конечная сетка пикселей с шириной и высотой. Координаты фигуры — положение её точек на этой сетке. Viewbox — записанное описание области векторного рисунка. В двух одинаковых квадратах выше менялись только границы viewbox; в третьем вызван scale(1.5,1.5), поэтому координаты фигуры умножены на полтора. Реальные размеры PNG задаются newImage и не меняются этим setter.
Если нужно сделать все элементы крупнее, выберите новый размер холста и преобразование координат вместе. Не обещайте, что метка DPI сама превратит маленький готовый PNG в подробную большую картинку. Для сохранённых команд можно заново выполнить геометрию с нужным масштабом; для готового raster применяют отдельный resize, который интерполирует имеющиеся пиксели.
Почему reset не стирает PNG и не равен полному сбросу


<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(600, 200, 'white');
$image->setImageFormat('png');
$original = new ImagickDraw();
$original->setStrokeColor('none');
$original->setFillColor('#146c74');
$original->rectangle(20, 50, 120, 150);
$image->drawImage($original);
$original->resetVectorGraphics();
$retained = $original->getFillColor()->getColor();
if ($retained['r'] !== 20 || $retained['g'] !== 108 || $retained['b'] !== 116) {
throw new LogicException('Ожидалась сохранённая настройка fill');
}
$original->rectangle(220, 50, 320, 150);
$image->drawImage($original);
$original->resetVectorGraphics();
$original->setStrokeColor('none');
$original->setFillColor('#146c74');
$original->rectangle(420, 50, 520, 150);
$image->drawImage($original);
echo 'fill-getter=teal; commands=reapplied', "\n";
$original->clear();
$path = __DIR__ . '/first-reset-comparison.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'first-reset-comparison.png', "\n";
$image->clear();
Результат: first-reset-comparison.png 600×200. Getter после reset сохраняет бирюзовый цвет, но поток больше не содержит команды заливки. После её повторной записи третья фигура снова бирюзовая. Уже нарисованная первая фигура осталась на холсте. Консоль до имени файла: fill-getter=teal; commands=reapplied. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
При независимых задачах проще создать новый Draw и явно настроить его. Если объект сознательно переиспользуется, повторно запишите все нужные свойства перед фигурами. Ранее выполненный рисунок удаляется действиями над самим изображением, а не очисткой команды. Clear сбрасывает и свойства; resetVectorGraphics очищает только поток. Ни один из них не является undo для PNG.
Один утверждённый шаблон — три готовых карточки

Фоновая задача может использовать один проверенный шаблон для нескольких изображений. Здесь для наглядности три независимые панели собраны в один отчёт. CompositeImage помещает уже полученные пиксели панели по x=0,200,400; он не переносит исходные Draw-команды в большой холст.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(600, 300, 'white');
$image->setImageFormat('png');
$template = new ImagickDraw();
$template->setStrokeColor('none');
$template->setFillColor('#146c74');
$template->roundRectangle(15, 35, 175, 135, 12, 12);
$template->setFillColor('#ffe08a');
$template->circle(125, 85, 150, 85);
$template->setStrokeColor('white');
$template->setStrokeWidth(5);
$template->setFillColor('none');
$template->polyline([['x' => 112, 'y' => 85], ['x' => 122, 'y' => 96], ['x' => 139, 'y' => 75]]);
$template->comment('asset=parcel; version=1');
$saved = $template->getVectorGraphics();
foreach ([0, 1, 2] as $index) {
$draw = new ImagickDraw();
$draw->setVectorGraphics($saved);
$panel = new Imagick();
$panel->newImage(200, 200, 'white');
$panel->drawImage($draw);
$image->compositeImage($panel, Imagick::COMPOSITE_OVER, 200 * $index, 40);
$draw->clear();
$panel->clear();
}
echo 'one-trusted-template=three-visible-cards', "\n";
$template->clear();
$path = __DIR__ . '/three-replayed-parcels.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'three-replayed-parcels.png', "\n";
$image->clear();
Результат: three-replayed-parcels.png 600×300. Три одинаковые бирюзовые карточки с золотистыми кругами и белыми галочками. Каждый цикл создаёт собственные Draw и панель 200×200, импортирует один и тот же снимок, растеризует его и помещает на общий белый холст. Файл сохраняется один — этот отчёт, промежуточные панели остаются в памяти. Консоль до имени файла: one-trusted-template=three-visible-cards. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Foreach перебирает три индекса. Умножение 200 * $index вычисляет сдвиг панели, поэтому координаты шаблона не надо переписывать. Упражнение: сделайте четыре панели на холсте 800×300. Решение: newImage(800,300,...) и список [0,1,2,3]; ширина каждой панели и шаг 200 сохраняются. Добавлять только ещё одну итерацию при ширине 600 нельзя: последняя панель окажется за правым краем. Связанные понятия — foreach и условия, выражения.
Выбрать следующий шаг по задаче
- Нужны прежние команды позже — сохраните собственный DrawingWand XML и импортируйте его парным setter.
- Нужен файл изображения — создайте Imagick, выполните drawImage и writeImage.
- Нужна новая независимая очередь — новый Draw проще неявного переиспользования; после reset свойства для новой очереди задаются явно.
- Нужен другой размер — отдельно выберите холст и масштаб геометрии, не заменяйте их viewbox.
- Нужен комментарий разработчику — comment; нужна видимая подпись — annotation с нужным шрифтом.

Продолжение: геометрия и масштаб, состояние и независимые Draw, первые видимые надписи. Для браузерного SVG нужен отдельный корректный SVG-документ, а не переименование DrawingWand XML.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
ImagickDraw::getVectorGraphicsОдин настроенный значок должен воспроизводиться позже в другой задаче или после чтения своего файла.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::getVectorGraphics(): stringОдин настроенный значок должен воспроизводиться позже в другой задаче или после чтения своего файла.
Метод возвращает описание текущего DrawingWand: сохранённые настройки и поток векторных команд. Это обычная PHP-строка, которую можно хранить в переменной или файле. Ни PNG-пикселей, ни стандартного SVG-документа getter не создаёт. Очередь не очищается и ещё не выполняется.

Синтаксис, параметры и результат
ImagickDraw::getVectorGraphics(): stringПараметров нет: пустые скобки вызывают действие у текущего Draw.
string по официальной сигнатуре. Текущий binding превращает native-строку в PHP-строку и сам освобождает временный C-буфер; ручной free в PHP не нужен. Не приписываем getter недокументированный контракт false. Успешный снимок проверен двумя запусками; исчерпание памяти специально не моделировалось.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->roundRectangle(30, 30, 300, 170, 18, 18);
$draw->setFillColor('#ffe08a');
$draw->circle(245, 100, 280, 100);
$draw->setFillColor('none');
$draw->setStrokeColor('white');
$draw->setStrokeWidth(8);
$draw->polyline([['x' => 226, 'y' => 100], ['x' => 240, 'y' => 114], ['x' => 264, 'y' => 86]]);
$draw->setStrokeColor('none');
$draw->setFillColor('#bdebe2');
$draw->rectangle(55, 62, 175, 76);
$draw->rectangle(55, 95, 145, 109);
$draw->rectangle(55, 128, 165, 142);
$saved = $draw->getVectorGraphics();
if (!str_contains($saved, '<drawing-wand>') || !str_contains($saved, 'roundrectangle')) {
throw new LogicException('Ожидался снимок своей очереди');
}
echo 'snapshot=string; command=roundrectangle', "\n";
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/exported-parcel.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'exported-parcel.png', "\n";
$image->clear();
Результат: exported-parcel.png 360×200. Бирюзовая карточка с тремя мятными строками и золотистым кругом с белой галочкой. Переменная $saved содержит XML DrawingWand с командами; PNG появляется отдельно после drawImage/writeImage. Консоль до имени файла: snapshot=string; command=roundrectangle. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Сохранить собственный шаблон в файл и воспроизвести его
Фоновая задача должна заново получить тот же значок, не повторяя код геометрии. Сохраним снимок в drawing.xml, прочитаем его и построим PNG. Файл создаётся самим примером в его папке; источник доверенный.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->roundRectangle(30, 30, 300, 170, 18, 18);
$draw->setFillColor('#ffe08a');
$draw->circle(245, 100, 280, 100);
$draw->setFillColor('none');
$draw->setStrokeColor('white');
$draw->setStrokeWidth(8);
$draw->polyline([['x' => 226, 'y' => 100], ['x' => 240, 'y' => 114], ['x' => 264, 'y' => 86]]);
$draw->setStrokeColor('none');
$draw->setFillColor('#bdebe2');
$draw->rectangle(55, 62, 175, 76);
$draw->rectangle(55, 95, 145, 109);
$draw->rectangle(55, 128, 165, 142);
$saved = $draw->getVectorGraphics();
$templatePath = __DIR__ . '/drawing.xml';
if (file_put_contents($templatePath, $saved) !== strlen($saved)) {
throw new RuntimeException('Снимок записан не полностью');
}
$loaded = file_get_contents($templatePath);
if ($loaded === false || $loaded !== $saved) {
throw new RuntimeException('Снимок не прочитан точно');
}
$replay = new ImagickDraw();
$replay->setVectorGraphics($loaded);
$image->drawImage($replay);
echo 'drawing.xml=written-and-read; replay=ready', "\n";
$draw->clear();
$replay->clear();
$path = __DIR__ . '/parcel-from-saved-file.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'parcel-from-saved-file.png', "\n";
$image->clear();
Результат: parcel-from-saved-file.png 360×200. Та же карточка восстановлена из реально созданного drawing.xml. В файле остаются команды, а в PNG — пиксели их исполнения. Это снимок для совместимого DrawingWand; не обещана бессрочная совместимость разных ImageMagick и не гарантируется наличие внешних шрифтов/изображений. Консоль до имени файла: drawing.xml=written-and-read; replay=ready. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Не называйте результат SVG и не меняйте расширение файла в надежде получить SVG. Формат DrawingWand XML с вложенными MVG-командами нужен парному setVectorGraphics. Он не упаковывает шрифты/внешние картинки и не гарантирует совместимость любых будущих версий. Снимок после reset не содержит удалённых команд.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::setVectorGraphics · ImagickDraw::render · ImagickDraw::resetVectorGraphics · ImagickDraw::setViewbox · ImagickDraw::comment. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
ImagickDraw::setVectorGraphicsФоновая задача получает утверждённый шаблон и должна нарисовать его на новом холсте без повторения исходных вызовов rectangle/circle.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::setVectorGraphics(string $xml): boolФоновая задача получает утверждённый шаблон и должна нарисовать его на новом холсте без повторения исходных вызовов rectangle/circle.
Передайте XML, который создал getVectorGraphics совместимой сборки, либо утверждённый формат такого же DrawingWand. Setter импортирует состояние и команды в этот Draw; пиксели создаст отдельный drawImage. В нашем runtime getter уже даёт корень drawing-wand: добавление root из старого официального примера ломает последующее рисование.

Синтаксис, параметры и результат
ImagickDraw::setVectorGraphics(string $xml): bool| Параметр | Что передать и зачем |
|---|---|
| $xml | string, обязательный снимок DrawingWand XML. Наши два источника — собственный getter и приложенный неизменённый parcel.xml. Это не путь, не байты PNG, не произвольный SVG path и не сырой MVG-текст без его XML-структуры. |
bool: true при успешном native-импорте; официальный контракт предусматривает false при отказе. Текущий PHP wrapper при native MagickFalse выбрасывает исключение вместо обычного возврата false; обработайте исключение binding, если читаете заменяемый источник. Успешный импорт ещё не доказывает, что все команды удастся растеризовать.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->roundRectangle(30, 30, 300, 170, 18, 18);
$draw->setFillColor('#ffe08a');
$draw->circle(245, 100, 280, 100);
$draw->setFillColor('none');
$draw->setStrokeColor('white');
$draw->setStrokeWidth(8);
$draw->polyline([['x' => 226, 'y' => 100], ['x' => 240, 'y' => 114], ['x' => 264, 'y' => 86]]);
$draw->setStrokeColor('none');
$draw->setFillColor('#bdebe2');
$draw->rectangle(55, 62, 175, 76);
$draw->rectangle(55, 95, 145, 109);
$draw->rectangle(55, 128, 165, 142);
$saved = $draw->getVectorGraphics();
$replay = new ImagickDraw();
if (!$replay->setVectorGraphics($saved)) {
throw new RuntimeException('Не удалось восстановить свой рисунок');
}
$image->drawImage($replay);
$draw->clear();
$replay->clear();
$path = __DIR__ . '/restored-parcel.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'restored-parcel.png', "\n";
$image->clear();
Результат: restored-parcel.png 360×200. Карточка восстановлена из строки, полученной своим getVectorGraphics. В проверенной сборке строка уже содержит drawing-wand и передана без дополнительного root. Setter не читает PNG и не преобразует произвольный SVG. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Прочитать приложенный проверенный шаблон, а не произвольный SVG
Приложение использует утверждённый шаблон parcel.xml. Проверим ограниченный размер и точные байты, затем импортируем. Проверка хеша здесь привязывает один учебный файл к его известному содержимому; она не делает безопасным любой чужой документ.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$xml = file_get_contents(__DIR__ . '/parcel.xml');
if ($xml === false || strlen($xml) > 10000 || hash('sha256', $xml) !== 'ab402d53b98109a3ea3bf9f75d09229a8270c79ad4ad4425e28b61ea318e4ae0') {
throw new RuntimeException('Ожидался неизменённый приложенный parcel.xml');
}
$draw = new ImagickDraw();
if (!$draw->setVectorGraphics($xml)) {
throw new RuntimeException('Шаблон не импортирован');
}
$image->drawImage($draw);
echo 'parcel.xml=verified; replay=ready', "\n";
$draw->clear();
$path = __DIR__ . '/parcel-from-trusted-template.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'parcel-from-trusted-template.png', "\n";
$image->clear();
Результат: parcel-from-trusted-template.png 360×200. Карточка 360×200 восстановлена из parcel.xml, который находится в архиве. Известный шаблон содержит только фиксированные векторные команды, без путей к ресурсам и шрифтов. Не принимайте такие команды напрямую от посетителя сайта и не считайте успешный XML-разбор полной проверкой будущей растеризации. Консоль до имени файла: parcel.xml=verified; replay=ready. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Импорт перестраивает контекст, поэтому после неудачного импорта безопаснее отбросить Draw и создать новый. Чужие векторные команды могут потребовать ресурсы/пути и дорогое рисование; в этой главе исполняются только собственные фиксированные шаблоны. Ограничение размера/хеш известного файла — локальный договор, не универсальный фильтр опасного XML. Старый root workaround не применять вслепую.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::getVectorGraphics · ImagickDraw::render · ImagickDraw::resetVectorGraphics · ImagickDraw::setViewbox · ImagickDraw::comment. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
ImagickDraw::renderВызов с названием render кажется способом получить PNG, но самостоятельный Draw не получает созданный отдельно холст автоматически.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::render(): boolВызов с названием render кажется способом получить PNG, но самостоятельный Draw не получает созданный отдельно холст автоматически.
Официальное назначение — исполнить накопленные команды на внутреннем image DrawingWand. Метод не принимает Imagick и не возвращает файл. В проверенном PHP Imagick 3.8.1 у отдельного Draw нет подходящего пиксельного холста: render реально выбрасывает ImagickException. Оба примера ловят этот конкретный отказ и показывают реальный PNG через $image->drawImage($draw).

Синтаксис, параметры и результат
ImagickDraw::render(): boolПараметров нет: пустые скобки вызывают действие у текущего Draw.
bool: официально true при успехе и false при отказе. Текущий wrapper превращает native-отказ в исключение; наблюдаемая ошибка данного runtime имеет класс ImagickException. Не заменяйте try/catch проверкой одного false и не выдавайте обработанный отказ за успешный render. Точный английский текст и детали C зависят от сборки.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 50, 120, 150);
try {
$draw->render();
throw new LogicException('В проверенной сборке ожидался отказ отдельного Draw');
} catch (ImagickException $error) {
echo 'render=ImagickException; fallback=drawImage', "\n";
}
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/render-diagnostic-fallback.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'render-diagnostic-fallback.png', "\n";
$image->clear();
Результат: render-diagnostic-fallback.png 360×200. Видимый бирюзовый квадрат создан вызовом $image->drawImage($draw). Вызов $draw->render() реально выполнен и обработан как ImagickException; создание отдельного $image не связало его с внутренним Draw. Это пример диагностированного отказа и рабочей замены, а не успешного render(). Консоль до имени файла: render=ImagickException; fallback=drawImage. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Перехватить отказ render и продолжить сохранение своей карточки
Сервис не должен остаться без файла из-за неверного предположения о render(). Воспроизведём это предположение явно, обработаем native-исключение, затем передадим сохранённую очередь новому Draw и настоящему холсту через drawImage.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->roundRectangle(30, 30, 300, 170, 18, 18);
$draw->setFillColor('#ffe08a');
$draw->circle(245, 100, 280, 100);
$draw->setFillColor('none');
$draw->setStrokeColor('white');
$draw->setStrokeWidth(8);
$draw->polyline([['x' => 226, 'y' => 100], ['x' => 240, 'y' => 114], ['x' => 264, 'y' => 86]]);
$draw->setStrokeColor('none');
$draw->setFillColor('#bdebe2');
$draw->rectangle(55, 62, 175, 76);
$draw->rectangle(55, 95, 145, 109);
$draw->rectangle(55, 128, 165, 142);
$saved = $draw->getVectorGraphics();
try {
$draw->render();
throw new LogicException('Ожидался диагностический отказ render');
} catch (ImagickException $error) {
echo 'render=handled; separate-canvas=not-bound', "\n";
}
$replay = new ImagickDraw();
$replay->setVectorGraphics($saved);
$image->drawImage($replay);
echo 'drawImage=rendered', "\n";
$draw->clear();
$replay->clear();
$path = __DIR__ . '/parcel-after-render-diagnostic.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'parcel-after-render-diagnostic.png', "\n";
$image->clear();
Результат: parcel-after-render-diagnostic.png 360×200. PNG с реальной карточкой создан рабочим drawImage после обработанного отказа render. Снимок взят до диагностического вызова. Точный текст native-ошибки зависит от сборки, поэтому пользовательская диагностика опирается на класс исключения, а не на английское сообщение с номером строки C. Консоль до имени файла: render=handled; separate-canvas=not-bound; drawImage=rendered. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Ни newImage у другого объекта, ни вызов drawImage перед render не являются публичной привязкой внутреннего image Draw. Для прикладного рисования используйте Imagick::drawImage, а для файла — writeImage. Не повторяйте render в цикле как попытку завершить очередь; устраните неверную операцию. Наши примеры отказа версионно привязаны и намеренно требуют ImagickException в проверенной сборке.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::getVectorGraphics · ImagickDraw::setVectorGraphics · ImagickDraw::resetVectorGraphics · ImagickDraw::setViewbox · ImagickDraw::comment. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
ImagickDraw::resetVectorGraphicsДолго живущий объект уже накопил фигуру, а для следующего файла нужна другая фигура без повторного исполнения старой.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::resetVectorGraphics(): boolДолго живущий объект уже накопил фигуру, а для следующего файла нужна другая фигура без повторного исполнения старой.
Reset удаляет накопленный векторный поток; сохранённые свойства Draw при этом не становятся автоматически значениями по умолчанию. Это не очистка уже нарисованного PNG. Важный нюанс проверен на пикселях: getter ещё показывает бирюзовый fill, но удалённой команды fill больше нет, и новая фигура без её записи растеризуется чёрной. Заново задайте нужные настройки перед новыми фигурами либо создайте новый Draw.

Синтаксис, параметры и результат
ImagickDraw::resetVectorGraphics(): boolПараметров нет: пустые скобки вызывают действие у текущего Draw.
bool; официально true при успехе. Wrapper вызывает void DrawResetVectorGraphics и возвращает true. Операция ничего не возвращает в виде рисунка/списка удалённых команд. Она не является заменой clear, который также сбрасывает свойства.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 50, 120, 150);
$draw->resetVectorGraphics();
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(220, 50, 320, 150);
$image->drawImage($draw);
echo 'old-rectangle=removed; new-rectangle=teal', "\n";
$draw->clear();
$path = __DIR__ . '/reset-before-raster.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'reset-before-raster.png', "\n";
$image->clear();
Результат: reset-before-raster.png 360×200. Слева белое место: старая фигура была удалена из очереди до её исполнения. Справа бирюзовый квадрат. После reset настройки заново записаны командами перед новой фигурой; готовые пиксели reset не стирал. Консоль до имени файла: old-rectangle=removed; new-rectangle=teal. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Не путать сохранённую настройку и очищенную очередь
Слева исполним оригинальный квадрат. После reset getter ещё помнит бирюзовый fill, но команда fill из потока удалена: новая фигура без повторных настроек получается чёрной. Затем повторим setter перед третьей фигурой. Готовый левый квадрат при этом остаётся на том же холсте.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(600, 200, 'white');
$image->setImageFormat('png');
$original = new ImagickDraw();
$original->setStrokeColor('none');
$original->setFillColor('#146c74');
$original->rectangle(20, 50, 120, 150);
$image->drawImage($original);
$original->resetVectorGraphics();
$retained = $original->getFillColor()->getColor();
if ($retained['r'] !== 20 || $retained['g'] !== 108 || $retained['b'] !== 116) {
throw new LogicException('Ожидалась сохранённая настройка fill');
}
$original->rectangle(220, 50, 320, 150);
$image->drawImage($original);
$original->resetVectorGraphics();
$original->setStrokeColor('none');
$original->setFillColor('#146c74');
$original->rectangle(420, 50, 520, 150);
$image->drawImage($original);
echo 'fill-getter=teal; commands=reapplied', "\n";
$original->clear();
$path = __DIR__ . '/reset-settings-versus-commands.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'reset-settings-versus-commands.png', "\n";
$image->clear();
Результат: reset-settings-versus-commands.png 600×200. Три квадрата: бирюзовый (20..120), чёрный (220..320), бирюзовый (420..520), все y=50..150. В середине показан намеренный неправильный результат после удаления команд настройки; справа — явная повторная запись fill/stroke. Reset не равен clear и не стирает уже нарисованный левый квадрат. Консоль до имени файла: fill-getter=teal; commands=reapplied. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Reset не отменяет изменения уже выполненного drawImage и не работает как ластик. Не доказывайте цвет нового рисунка одним getFillColor после reset: сами команды надо восстановить. Для независимых задач новый Draw часто проще и понятнее; при его создании все настройки задают явно. Не очищайте объект, чьи команды ещё понадобятся, не сохранив снимок.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::getVectorGraphics · ImagickDraw::setVectorGraphics · ImagickDraw::render · ImagickDraw::setViewbox · ImagickDraw::comment. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
ImagickDraw::setViewboxСохранённый шаблон должен иметь понятную область рисунка; при новом размере нужно отличать её описание от фактического масштабирования.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::setViewbox(int $left_x, int $top_y, int $right_x, int $bottom_y): boolСохранённый шаблон должен иметь понятную область рисунка; при новом размере нужно отличать её описание от фактического масштабирования.
Четыре целых задают левую верхнюю и правую нижнюю координаты векторной области. Обычно они согласованы с размером создаваемого холста. Эти данные нужны формату/просмотрщику, но не выделяют пиксели в отдельном Imagick. При проверенном drawImage изменение одного viewbox не увеличило фигуру: для этого явно использован scale.

Синтаксис, параметры и результат
ImagickDraw::setViewbox(int $left_x, int $top_y, int $right_x, int $bottom_y): bool| Параметр | Что передать и зачем |
|---|---|
| $left_x | int, левая x-координата; для обычного рисунка 0. |
| $top_y | int, верхняя y-координата; для обычного рисунка 0. Историческое описание «left y» читаем как верхнюю границу. |
| $right_x | int, правая x-координата, а не отдельная ширина. При left_x=0 обычно равна ширине. |
| $bottom_y | int, нижняя y-координата, а не отдельная высота. При top_y=0 обычно равна высоте. В примерах правая/нижняя границы больше левой/верхней. |
bool по сигнатуре, хотя краткий официальный prose говорит об отсутствии результата. Текущий wrapper передаёт четыре long в void DrawSetViewbox и возвращает true. Размер уже созданного PNG проверяется у Imagick; true setter не означает resize или проверку допустимой геометрии.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, 360, 200);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 50, 120, 150);
$saved = $draw->getVectorGraphics();
if (!str_contains($saved, 'viewbox 0 0 360 200')) {
throw new LogicException('Размер не записан в команды');
}
$image->drawImage($draw);
echo 'viewbox=0,0,360,200; PNG=360x200', "\n";
$draw->clear();
$path = __DIR__ . '/viewbox-matches-canvas.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'viewbox-matches-canvas.png', "\n";
$image->clear();
Результат: viewbox-matches-canvas.png 360×200. Квадрат от (20,50) до (120,150) на холсте 360×200. Viewbox записывает границы рисунка в векторные данные; реальный PNG 360×200 создан ранее newImage. Четыре числа — две пары координат, а не ширина/высота и не команда resize. Консоль до имени файла: viewbox=0,0,360,200; PNG=360x200. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Разделить границы viewbox и действительное увеличение геометрии
Нужен значок другого размера. Сравним два разных viewbox при одной и той же геометрии, затем увеличим геометрию явным scale. Так видно, какое действие на самом деле изменяет размер фигуры при drawImage.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(600, 200, 'white');
$image->setImageFormat('png');
foreach ([100, 200, 100] as $index => $right) {
$draw = new ImagickDraw();
$draw->setViewbox(0, 0, $right, 200);
$draw->translate(200 * $index, 0);
if ($index === 2) {
$draw->scale(1.5, 1.5);
}
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 40, 80, 100);
$image->drawImage($draw);
$draw->clear();
}
echo 'viewbox-only=same-geometry; explicit-scale=1.5', "\n";
$path = __DIR__ . '/viewbox-does-not-resize-pixels.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'viewbox-does-not-resize-pixels.png', "\n";
$image->clear();
Результат: viewbox-does-not-resize-pixels.png 600×200. Слева и в центре два одинаковых квадрата 60×60 по геометрии, несмотря на right_x 100 и 200. Справа scale(1.5,1.5) даёт квадрат 90×90. Сам PNG по-прежнему 600×200. Viewbox не заменяет scale/resize и не подбирает размер текста под прямоугольник. Консоль до имени файла: viewbox-only=same-geometry; explicit-scale=1.5. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Не подменяйте координаты right/bottom шириной/высотой при ненулевом начале. Не ожидайте автоматического переноса/масштабирования текста или обрезки PNG через viewbox. Для масштаба геометрии используйте scale/affine, для изменения пиксельного файла — соответствующий resize с понятным фильтром. Записывайте viewbox до фигур и выбирайте согласованную систему координат.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::getVectorGraphics · ImagickDraw::setVectorGraphics · ImagickDraw::render · ImagickDraw::resetVectorGraphics · ImagickDraw::comment. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
ImagickDraw::commentРазработчик открывает свой снимок и должен отличить начало значка от служебных линий, не добавляя надпись пользователю.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::comment(string $comment): boolРазработчик открывает свой снимок и должен отличить начало значка от служебных линий, не добавляя надпись пользователю.
Метод добавляет комментарий в векторный поток. Это заметка для чтения/отладки команд, которая не рисует буквы и не заменяет annotation. В примере две панели отличаются наличием пометок в снимке, но имеют строго одинаковые пиксели.

Синтаксис, параметры и результат
ImagickDraw::comment(string $comment): bool| Параметр | Что передать и зачем |
|---|---|
| $comment | string, текст пометки. В примерах это короткие постоянные однострочные значения asset=warehouse-parcel-v1 или stage=confirmation-mark. Не помещайте сюда секреты и непроверенный пользовательский ввод; векторный снимок могут открыть другие люди. |
bool по сигнатуре; сохранённый официальный prose говорит об отсутствии результата. Текущий wrapper вызывает void DrawComment и возвращает true. Результат не содержит готовую подпись, байты PNG или отдельный структурированный объект журнала.
Официальная доступность: PECL imagick 2, PECL imagick 3. В исходной записи нет отметок deprecated/removed и отдельной истории изменений. Там, где документация помечена неполной, эта отметка сохранена; отсутствие описанных ошибок не объявляется отсутствием отказов. Полные исходные поля и параметры сохранены в контракте карточки. Примеры PHP 8.2+ фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(360, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 50, 120, 150);
$draw->comment('asset=warehouse-parcel-v1');
$saved = $draw->getVectorGraphics();
if (!str_contains($saved, 'asset=warehouse-parcel-v1')) {
throw new LogicException('Служебная пометка не сохранена');
}
$image->drawImage($draw);
echo 'comment=saved-in-vector; visible-label=no', "\n";
$draw->clear();
$path = __DIR__ . '/comment-is-not-a-label.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'comment-is-not-a-label.png', "\n";
$image->clear();
Результат: comment-is-not-a-label.png 360×200. Только бирюзовый квадрат; слова asset=warehouse-parcel-v1 на PNG нет. Комментарий записан в поток команд для человека, читающего снимок, и не рисуется как annotation. Служебная пометка не является защищённым журналом или метаданными PNG. Консоль до имени файла: comment=saved-in-vector; visible-label=no. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Практическая задача: Пометить два этапа рисунка, не меняя его пиксели
Для отладки шаблона полезно увидеть в снимке, где начинается значок и где заканчивается проверочный знак. Добавим одноcтрочные постоянные комментарии только второму из двух одинаковых значков. Две панели должны остаться визуально одинаковыми.
<?php
declare(strict_types=1);
$image = new Imagick();
$image->newImage(400, 200, 'white');
$image->setImageFormat('png');
foreach ([false, true] as $index => $withComment) {
$draw = new ImagickDraw();
$draw->translate(200 * $index, 0);
if ($withComment) {
$draw->comment('stage=parcel-body');
}
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->rectangle(20, 40, 160, 160);
if ($withComment) {
$draw->comment('stage=confirmation-mark');
}
$draw->setFillColor('#ffe08a');
$draw->circle(90, 100, 125, 100);
$saved = $draw->getVectorGraphics();
if ($withComment && !str_contains($saved, 'stage=confirmation-mark')) {
throw new LogicException('Пометка не попала в снимок');
}
$image->drawImage($draw);
$draw->clear();
}
echo 'comments=two; expected-pixel-difference=0', "\n";
$path = __DIR__ . '/comments-do-not-change-pixels.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'comments-do-not-change-pixels.png', "\n";
$image->clear();
Результат: comments-do-not-change-pixels.png 400×200. Два бирюзовых прямоугольника с золотистыми кругами. В правом потоке есть две служебные пометки, в левом нет; сравнение соответствующих 200×200 панелей даёт одинаковые пиксели. Для видимой надписи нужен annotation и подходящий font, а не comment. Консоль до имени файла: comments=two; expected-pixel-difference=0. Распакуйте архив целиком в отдельную папку и выполните php example.php при PHP с imagick. Откройте PNG рядом с example.php обычным просмотрщиком при 100%. Повторный запуск заменит одноимённые учебные файлы. Шрифты, интернет и shell-команды этим примерам не нужны.
Ошибки, альтернативы и стоимость
Не путайте comment с metadata готового PNG или видимым текстом. В native-потоке пометка записывается как строка с #; перевод строки CR/LF во внешнем тексте способен превратить следующую строку в MVG-команду. Используйте постоянные однострочные пометки или отдельно отклоняйте CR/LF до comment; этот метод не экранирует произвольный ввод. Он также не доказывает авторство. Для видимого текста используйте annotation с подходящим шрифтом; для аудита — журнал приложения.
Неверный формат/импорт, отказ рисования, недоступный входной файл и отказ записи PNG — разные этапы. Setter не проверяет их все сразу. Try/catch перехватывает указанный класс исключения, а не любой возможный сбой приложения. Копия строки и импорт стоят памяти пропорционально размеру снимка; растеризация зависит от числа/сложности команд и площади холста. Сериализация не убирает эту работу и не обещает ускорение. Для неизменяемого готового размера часто достаточно кэшировать проверенный PNG; команды полезны, когда нужен новый холст или контролируемое изменение рисунка.
Другие шаги: ImagickDraw::getVectorGraphics · ImagickDraw::setVectorGraphics · ImagickDraw::render · ImagickDraw::resetVectorGraphics · ImagickDraw::setViewbox. Геометрия — фигуры, независимые состояния — clear/clone и очередь, видимый текст — annotation со шрифтом.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


