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

Дерево руководства
Глава 338 · После первых надписей
ImagickDraw: читаемая подложка, старая цена и правильная кириллица
Сохранить понятную карточку: зачеркнуть старую цену, выделить статус на цветном фоне и передать в renderer проверенную UTF-8 подпись с приложенным шрифтом.
Сохранить читаемый статус на цветной карточке
Человеку нужна видимая надпись «Заказ готов», которую можно отправить вместе с карточкой. На разноцветном фоне одним цветом букв не всегда удаётся получить читаемый результат. Подложим под строку отдельный золотистый цвет и сохраним PNG; затем разберём, чем это отличается от фона всего изображения и от бейджа с полями.

Распакуйте все файлы примера. Четыре файла font.php, font.ttf.b64, font-license.txt и font-metadata.json содержат подготовку неизменённого Open Sans Regular 1.10 с кириллицей и Apache License 2.0. Helper возвращает путь к локальному font.ttf, ничего не скачивая и не устанавливая. Создание надписи и базовая линия объяснены в первом тексте, координаты — в размещении подписей.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 350, 140);
$background->setFillColor('#c25732');
$background->rectangle(120, 20, 350, 140);
$image->drawImage($background);
$background->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('#ffe08a');
$draw->setTextEncoding('UTF-8');
$draw->annotation(20, 80, 'Заказ готов');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/first-highlighted-status.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'first-highlighted-status.png', "\n";
$image->clear();
Результат: first-highlighted-status.png 360×160. Цветная карточка остаётся прежней за пределами прямоугольника надписи. Подложка золотистая, сами буквы бирюзовые; это две разные настройки. Форма подложки привязана к метрикам строки, а не к размеру всей карточки. Последняя строка — first-highlighted-status.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
setFillColor('#146c74') задаёт цвет букв, setTextUnderColor('#ffe08a') — цвет прямоугольника под ними. annotation(20,80,'Заказ готов') записывает строку с началом x=20 и базовой линией y=80 при явных GRAVITY_FORGET/ALIGN_LEFT. setTextDecoration(Imagick::DECORATION_NO) оставляет её без линии. setTextEncoding('UTF-8') выбирает трактовку уже корректных байтов; font содержит нужные формы букв. drawImage выполняет очередь, writeImage сохраняет результат.
Разделить оформление, подложку и байты текста

| Задача | Что выбираем | Чего это не делает |
|---|---|---|
| Старая цена больше не действует | TextDecoration LINETHROUGH; новая цена NO | Не меняет цену в данных и не удаляет цифры. |
| Подпись теряется на фоне | TextUnderColor отдельно от fill | Не задаёт CSS padding и не заменяет font. |
| Правильная кириллица в PNG | Корректные UTF-8 байты + TextEncoding UTF-8 + нужные глифы | Не перекодирует случайные legacy-байты автоматически. |
Показать старую и новую цену в готовом ценнике
Покупателю важен смысл двух чисел. Зачёркивание старой цены и обычный более крупный новый размер делают различие видимым. Метод оформления задаётся перед конкретной надписью; сброс к NO не меняет ранее записанную строку.

<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(400, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#526b70');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_LINETHROUGH);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->annotation(20, 65, '1 500 руб.');
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setFontSize(32);
$draw->setFillColor('#146c74');
$draw->annotation(20, 135, '1 250 руб.');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/first-old-new-price.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'first-old-new-price.png', "\n";
$image->clear();
Результат: first-old-new-price.png 400×200. Старая цена 24 пункта зачёркнута, новая 32 пункта оставлена без линии. Цифры действительно нарисованы и читаемы; изменение font size не используется как способ задавать толщину зачёркивания. Последняя строка — first-old-new-price.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
В проверенном расширении зарегистрированы DECORATION_NO=1, UNDERLINE=2, OVERLINE=3 и LINETHROUGH=4. Используем полные имена Imagick::DECORATION_*, а не выдуманный DECORATION_NONE/DECORATION_UNDEFINED. В официальном getter-тексте есть случай нуля при отсутствии оформления; это не означает, что для отключения нужно угадывать имя константы.
Сначала проверить байты, затем рисовать русские буквы

Строка PHP хранит байты. UTF-8 — договор о том, как ими записаны символы. 'UTF-8' в setter не превращает Windows-1251/Latin-1 в этот договор. В двух файловых примерах вместе со шрифтом приложен label.txt: он содержит «Заказ № 42» и завершающий перевод строки. File_get_contents читает байты; preg_match('//u', $bytes) проверяет, что это допустимая UTF-8 последовательность. Пустой pattern с модификатором u не ищет слово и не конвертирует данные; при неверной последовательности результат не равен 1.

Даже корректная UTF-8 последовательность может содержать уже неверный текст (например, ранее дважды преобразованный mojibake) или символ без глифа в font. Проверка валидности не угадывает смысл и не чинит такие случаи. В учебном отказе hex2bin создаёт заранее известные некорректные для UTF-8 байты; они отклоняются, а не передаются в renderer. Для известной другой кодировки нужна отдельная явная конвертация с проверкой результата. Подробности — строки и байты, модификатор u и результат preg_match и чтение файлов.
Снимок цвета и поля бейджа — разные задачи


Текущая тема и её снимок цвета — разные объекты: новый цвет надо явно применить setter. Снимок не несёт координат/метрик надписи. Аналогично, undercolor создаёт фон строки по метрикам, но не готовую карточку с желаемым padding. Когда нужны заданные поля и фиксированная высота, полезнее отдельная геометрическая фигура. Проверяйте контраст результата; полупрозрачный цвет сохраняет влияние изображения под ним.
Собрать карточку заказа с выделенным статусом и новой ценой
Теперь номер заказа и статус читаются на двухцветной карточке, старая цена явно зачёркнута, а новая крупнее и без линии. В каждом текстовом контексте отдельно заданы UTF-8, font и оформление, поэтому зачёркивание старой цены не перейдёт в нижнюю подпись.

<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(480, 300, 'white');
$image->setImageFormat('png');
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 470, 280);
$background->setFillColor('#c25732');
$background->rectangle(160, 20, 470, 280);
$image->drawImage($background);
$background->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('#ffe08a');
$draw->setTextEncoding('UTF-8');
$draw->annotation(40, 60, 'Заказ № 42');
$image->drawImage($draw);
$draw->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#526b70');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_LINETHROUGH);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->annotation(40, 125, '1 500 руб.');
$image->drawImage($draw);
$draw->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(32);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('white');
$draw->setTextEncoding('UTF-8');
$draw->annotation(40, 185, '1 250 руб.');
$image->drawImage($draw);
$draw->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(16);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('#ffe08a');
$draw->setTextEncoding('UTF-8');
$draw->annotation(40, 245, 'Готов к выдаче');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/finished-order-report.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'finished-order-report.png', "\n";
$image->clear();
Результат: finished-order-report.png 480×300. Двухцветная панель (10,20)—(470,280). «Заказ № 42» 24 пункта на y=60 с золотистой подложкой; 1 500 руб. 24 пункта на y=125 зачёркнута; 1 250 руб. 32 пункта на y=185 без линии, на белой подложке; «Готов к выдаче» 16 пунктов на y=245 с отдельной золотистой подложкой. Начала x=40; все строки UTF-8 и поддержаны приложенным font. Последняя строка — finished-order-report.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Упражнение: замените статус на «Ожидает выдачи», сохранив нормальное оформление нижней строки. Решение: менять только последний текст, не переносить LineThrough из контекста старой цены. Если нужен бейдж со строго одинаковыми полями для статусов разной длины, измерьте строку и нарисуйте фигуру отдельно. Для файловой подписи попробуйте исправить label.txt, сохранив его в UTF-8; выбор другого имени encoding не заменяет это действие.
Дальше — измерение и размещение переменной подписи
- Decoration меняет служебную линию у текста; NO явно отключает её для следующих команд.
- Undercolor — цвет прямоугольника под строкой, fill — цвет букв, фон изображения — отдельная поверхность.
- GetTextUnderColor даёт независимую копию цвета; для применения нужен setter.
- UTF-8 настройка не перекодирует байты и не добавляет глифы; вход и font проверяются отдельно.
Продолжение: опоры и выравнивание, интервалы слов и строк, метрики текста, бейдж с собственными полями.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
ImagickDraw::getTextDecorationКомпонент должен сохранить оформление темы либо временно убрать зачёркивание у заголовка и вернуть его старой цене.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::getTextDecoration(): intКомпонент должен сохранить оформление темы либо временно убрать зачёркивание у заголовка и вернуть его старой цене.
Getter читает int enum этого Draw. Он не распознаёт подчёркнутые или перечёркнутые пиксели и не возвращает длину линии. Полученный enum явно передаётся setter нового объекта либо сохраняется перед временным изменением состояния.

Синтаксис, параметры и результат
ImagickDraw::getTextDecoration(): intАргументов нет: пустые скобки читают настройку текущего Draw.
int — DECORATION_*; официальный текст предусматривает 0 при отсутствии настройки. В реально проверенном свежем Draw возвращается DECORATION_NO (1). Ноль из описания не следует объявлять аварийным false; для явного отключения используем зарегистрированную DECORATION_NO, а не выдуманные DECORATION_NONE/DECORATION_UNDEFINED.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$theme = new ImagickDraw();
$theme->setTextDecoration(Imagick::DECORATION_UNDERLINE);
$decoration = $theme->getTextDecoration();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextDecoration($decoration);
$draw->annotation(20, 65, 'Проверено');
echo 'decoration=Underline; type=', get_debug_type($decoration), "\n";
$theme->clear();
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/copied-decoration.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'copied-decoration.png', "\n";
$image->clear();
Результат: copied-decoration.png 360×160. Надпись «Проверено» подчёркнута. Новый Draw получил int настройки из темы; getter не вернул готовую линию или рисунок. Шрифт, цвет и плотность нового объекта задаются отдельно. Перед именем файла консоль: decoration=Underline; type=int. Последняя строка — copied-decoration.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Временно убрать зачёркивание у заголовка и вернуть его старой цене
Тема компонента старых цен уже содержит LineThrough. Заголовок «Акция» должен остаться обычным. Сохраним прочитанный enum, отключим оформление только для заголовка и вернём перед старой ценой.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(400, 180, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_LINETHROUGH);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$previous = $draw->getTextDecoration();
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->annotation(20, 50, 'Акция');
$draw->setTextDecoration($previous);
$draw->annotation(20, 110, '1 500 руб.');
echo 'restored=LineThrough', "\n";
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/restored-price-decoration.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'restored-price-decoration.png', "\n";
$image->clear();
Результат: restored-price-decoration.png 400×180. Сверху обычный заголовок «Акция», ниже зачёркнутые «1 500 руб.». Сохранённый getter enum участвует в восстановлении; он не считывает перечёркнутую линию с PNG и не меняет уже записанный заголовок. Перед именем файла консоль: restored=LineThrough. Последняя строка — restored-price-decoration.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Прочитанный enum не переносит файл шрифта, цвет и размер. Форма служебной линии зависит от font и renderer. Не выдавайте getter за измерение толщины/высоты линии или проверку наличия скидки в данных приложения.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::setTextDecoration · ImagickDraw::getTextUnderColor · ImagickDraw::setTextUnderColor · ImagickDraw::getTextEncoding · ImagickDraw::setTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
ImagickDraw::setTextDecorationЧитателю нужно визуально отличить отменённую старую цену от новой, либо выделить проверенную строку подчёркиванием.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::setTextDecoration(int $decoration): boolЧитателю нужно визуально отличить отменённую старую цену от новой, либо выделить проверенную строку подчёркиванием.
Оформление задаётся до annotation и относится к записываемому тексту. DECORATION_UNDERLINE добавляет линию снизу, OVERLINE — сверху, LINETHROUGH — через текст; NO отключает её для следующих команд. Это оформление рисунка, не изменение самого текста и не HTML-тег ссылки. Уже записанная цена не теряет линию после последующего сброса.

Синтаксис, параметры и результат
ImagickDraw::setTextDecoration(int $decoration): bool| Параметр | Что передать и зачем |
|---|---|
| $decoration | int, обязательная именованная константа Imagick::DECORATION_NO, UNDERLINE, OVERLINE или LINETHROUGH с полным префиксом DECORATION_. В проверенном расширении NO=1, остальные 2/3/4; используйте имена вместо чисел. Существует исторический alias LINETROUGH, но в коде выбран правильно написанный LINETHROUGH. Не передавайте строку 'underline' вместо enum. |
bool по signature. Текущий wrapper вызывает void DrawSetTextDecoration и возвращает true; официальное prose «Nothing is returned» сохранено, расхождение объяснено. Bool не означает, что произвольный int проверен или PNG уже создан.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(640, 180, 'white');
$image->setImageFormat('png');
foreach ([Imagick::DECORATION_NO, Imagick::DECORATION_UNDERLINE, Imagick::DECORATION_OVERLINE, Imagick::DECORATION_LINETHROUGH] as $index => $decoration) {
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextDecoration($decoration);
$draw->annotation(20 + $index * 160, 60, 'Цена');
$image->drawImage($draw);
$draw->clear();
}
$path = __DIR__ . '/four-text-decorations.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'four-text-decorations.png', "\n";
$image->clear();
Результат: four-text-decorations.png 640×180. Четыре одинаковых «Цена» на y=60 с началами x=20,180,340,500: без линии, с подчёркиванием, с линией сверху и с зачёркиванием. Положение/толщина служебной линии определяются шрифтовыми метриками и renderer, а не произвольным CSS padding. Последняя строка — four-text-decorations.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Показать старую и новую цену разными способами
Покупателю нужно увидеть, какая цена больше не действует и какую платить сейчас. Первую зачеркнём и сделаем менее заметной, вторую оставим без оформления и крупнее. Это понятнее, чем просто поменять цифры без подписи старого значения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(400, 200, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#526b70');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_LINETHROUGH);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->annotation(20, 65, '1 500 руб.');
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setFontSize(32);
$draw->setFillColor('#146c74');
$draw->annotation(20, 135, '1 250 руб.');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/old-and-new-price.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'old-and-new-price.png', "\n";
$image->clear();
Результат: old-and-new-price.png 400×200. Верхняя цена 1 500 руб. серая и зачёркнутая, 24 пункта, baseline 65. Нижняя 1 250 руб. бирюзовая и без линии, 32 пункта, baseline 135. Сброс — именованная DECORATION_NO; текущий шрифт и холст позволяют обеим строкам поместиться. Последняя строка — old-and-new-price.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Не обещайте произвольную толщину/отступ линии через этот метод. Для специальной графической линии с заданными координатами используйте геометрию отдельно и при необходимости измерьте текст. Цена должна оставаться читаемой: жирная вручную нарисованная полоса может скрыть цифры. Проверяйте собственные font/размер, а не переносите старый дефект другой версии как универсальное правило.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::getTextDecoration · ImagickDraw::getTextUnderColor · ImagickDraw::setTextUnderColor · ImagickDraw::getTextEncoding · ImagickDraw::setTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
ImagickDraw::getTextUnderColorНовому статусу нужен цвет темы, а для более контрастной версии надо изменить его прозрачность, сохранив исходную тему.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::getTextUnderColor(): ImagickPixelНовому статусу нужен цвет темы, а для более контрастной версии надо изменить его прозрачность, сохранив исходную тему.
Getter создаёт отдельный ImagickPixel со снимком цвета и alpha. Это не живая ссылка на Draw и не готовый прямоугольник с координатами. Изменение снимка через setColor не меняет исходную тему; для применения передайте снимок нужному setTextUnderColor.

Синтаксис, параметры и результат
ImagickDraw::getTextUnderColor(): ImagickPixelАргументов нет: пустые скобки читают настройку текущего Draw.
ImagickPixel — отдельный объект цвета. В текущем PHP binding для него выделяется новый PixelWand; за освобождение памяти отвечает binding/PHP, ручной free не требуется. Цвет с alpha передаётся целиком. В примере прозрачность читается через getColorValue(Imagick::COLOR_ALPHA) как нормализованный float: 0 прозрачно, 1 непрозрачно; квантование может дать около 0.5000076 вместо ровно 0.5.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$theme = new ImagickDraw();
$theme->setTextUnderColor('#ffe08a');
$under = $theme->getTextUnderColor();
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 350, 140);
$background->setFillColor('#c25732');
$background->rectangle(120, 20, 350, 140);
$image->drawImage($background);
$background->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextUnderColor($under);
$draw->annotation(20, 80, 'Заказ готов');
echo 'under-type=', get_debug_type($under), "\n";
$theme->clear();
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/copied-text-background.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'copied-text-background.png', "\n";
$image->clear();
Результат: copied-text-background.png 360×160. Бирюзовый «Заказ готов» имеет золотистую подложку на двухцветной карточке. Getter дал отдельный ImagickPixel, и новый Draw явно получил этот цвет. Фон всего изображения не менялся. Перед именем файла консоль: under-type=ImagickPixel. Последняя строка — copied-text-background.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Сделать копию подложки непрозрачной для важного статуса
Тема содержит золотистый цвет с alpha 0.5. На пёстром фоне важному статусу нужна более однородная подложка. Изменим полученную копию и передадим её новому Draw; исходная тема сохранит свою прозрачность.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$theme = new ImagickDraw();
$theme->setTextUnderColor('rgba(255,224,138,0.5)');
$under = $theme->getTextUnderColor();
$alpha = $under->getColorValue(Imagick::COLOR_ALPHA);
if ($alpha < 0.8) {
$under->setColor('#ffe08a');
}
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 350, 140);
$background->setFillColor('#c25732');
$background->rectangle(120, 20, 350, 140);
$image->drawImage($background);
$background->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextUnderColor($under);
$draw->annotation(20, 80, 'Заказ готов');
$original = $theme->getTextUnderColor();
echo 'theme-alpha=', round($original->getColorValue(Imagick::COLOR_ALPHA), 2), '; applied-alpha=', round($under->getColorValue(Imagick::COLOR_ALPHA), 2), "\n";
$theme->clear();
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/opaque-copy-for-status.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'opaque-copy-for-status.png', "\n";
$image->clear();
Результат: opaque-copy-for-status.png 360×160. Статус имеет непрозрачную золотистую подложку, а исходная тема сохраняет alpha около 0.5. Alpha прочитана нормализованным getColorValue(COLOR_ALPHA), округление касается только диагностики. Изменение ImagickPixel не действует на тему до отдельного setter. Перед именем файла консоль: theme-alpha=0.5; applied-alpha=1. Последняя строка — opaque-copy-for-status.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Не считайте, что редактирование возвращённого Pixel сразу обновит рисунок или настройки темы. Getter не измеряет рамку текста и не читает фон из готового PNG. Alpha и цвет букв — разные свойства; изменение подложки не исправляет нечитаемые глифы или испорченную кодировку.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::getTextDecoration · ImagickDraw::setTextDecoration · ImagickDraw::setTextUnderColor · ImagickDraw::getTextEncoding · ImagickDraw::setTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
ImagickDraw::setTextUnderColorКороткий статус должен читаться на неоднородном фоне, даже когда цвет букв сам по себе сливается с отдельными участками изображения.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::setTextUnderColor(ImagickPixel|string $under_color): boolКороткий статус должен читаться на неоднородном фоне, даже когда цвет букв сам по себе сливается с отдельными участками изображения.
Метод задаёт цвет прямоугольника под последующей текстовой аннотацией. Fill остаётся цветом букв; фон всего изображения задаётся отдельно. Размер подложки рассчитывается из метрик аннотации, а не из нашего желаемого padding. Непрозрачный цвет закрывает фон под строкой, полунепрозрачный смешивается с ним, 'none' отключает подложку.

Синтаксис, параметры и результат
ImagickDraw::setTextUnderColor(ImagickPixel|string $under_color): bool| Параметр | Что передать и зачем |
|---|---|
| $under_color | обязательный ImagickPixel|string: объект цвета или понятная ImageMagick строка, например '#ffe08a', 'rgba(255,224,138,0.5)' либо 'none'. Это не цвет всего холста, не путь к фоновой картинке и не размер отступа. Неверная строка цвета может привести к ошибке разбора; в примерах используются фиксированные корректные цвета. |
bool по сигнатуре; текущий wrapper преобразует строку/Pixel в цвет, копирует его в native Draw и возвращает true. При отказе преобразования возможен error/false путь binding. Исходное prose «Nothing is returned» сохранено отдельно; возвращается не изображение и не координаты подложки.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(640, 180, 'white');
$image->setImageFormat('png');
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 630, 160);
$image->drawImage($background);
$background->clear();
foreach (['none', '#ffe08a', 'rgba(255,224,138,0.5)'] as $index => $color) {
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextUnderColor($color);
$draw->annotation(20 + $index * 210, 60, 'Цена');
$image->drawImage($draw);
$draw->clear();
}
$path = __DIR__ . '/three-text-backgrounds.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'three-text-backgrounds.png', "\n";
$image->clear();
Результат: three-text-backgrounds.png 640×180. Три «Цена» на одинаковой мятной подложке: без text undercolor, с непрозрачным #ffe08a и с тем же цветом при alpha 0.5. Последний смешивается с мятным фоном. Заливка букв остаётся бирюзовой во всех случаях; полунепрозрачный фон текста не делает буквы прозрачными. Последняя строка — three-text-backgrounds.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Отличить автоматическую подложку текста от бейджа с полями
Для одной короткой надписи хватает undercolor, а бейджу ниже нужны заданные поля вокруг букв. Покажем обе задачи: сверху фон рассчитан по метрикам текста, снизу отдельный прямоугольник с явными координатами, а text undercolor отключён.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(400, 220, 'white');
$image->setImageFormat('png');
$background = new ImagickDraw();
$background->setStrokeColor('none');
$background->setFillColor('#bdebe2');
$background->rectangle(10, 20, 390, 200);
$background->setFillColor('#c25732');
$background->rectangle(133, 20, 390, 200);
$image->drawImage($background);
$background->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('#ffe08a');
$draw->setTextEncoding('UTF-8');
$draw->annotation(35, 65, 'Готово');
$image->drawImage($draw);
$draw->clear();
$badge = new ImagickDraw();
$badge->setStrokeColor('none');
$badge->setFillColor('#ffe08a');
$badge->rectangle(20, 115, 180, 185);
$image->drawImage($badge);
$badge->clear();
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->setTextUnderColor('none');
$draw->annotation(35, 160, 'Готово');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/status-background-and-padding.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'status-background-and-padding.png', "\n";
$image->clear();
Результат: status-background-and-padding.png 400×220. Два «Готово» на двухцветной карточке. У верхнего фон ограничен прямоугольником по метрикам. Нижний расположен внутри заранее нарисованного бейджа (20,115)—(180,185), поэтому вокруг него есть управляемое свободное место. Undercolor не является CSS padding и не рисует скругления автоматически. Последняя строка — status-background-and-padding.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Undercolor не является CSS padding: не обещайте поля, скругления или одинаковую высоту любых строк. Для бейджа с заданными полями рисуйте отдельную фигуру и выберите координаты текста. Прозрачная подложка сохраняет влияние исходного фона на контраст, а не гарантирует читаемость на любой фотографии. Устанавливайте 'none' перед обычной следующей подписью или создайте отдельный Draw.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::getTextDecoration · ImagickDraw::setTextDecoration · ImagickDraw::getTextUnderColor · ImagickDraw::getTextEncoding · ImagickDraw::setTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
ImagickDraw::getTextEncodingКомпонент получает Draw с неизвестной начальной настройкой и должен договориться о UTF-8, либо переносит эту политику в новый объект перед чтением файла.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::getTextEncoding(): false|stringКомпонент получает Draw с неизвестной начальной настройкой и должен договориться о UTF-8, либо переносит эту политику в новый объект перед чтением файла.
Getter возвращает строку настройки либо false. Он не определяет кодировку текста, файла или HTTP-ответа и не проверяет целостность байтов. False означает, что настройка не задана; пустая строка после setTextEncoding('') означает запрос системного значения по умолчанию. Для воспроизводимых примеров выбираем явное 'UTF-8'.

Синтаксис, параметры и результат
ImagickDraw::getTextEncoding(): false|stringАргументов нет: пустые скобки читают настройку текущего Draw.
false|string. В native-проверке свежий объект дал false, после явного UTF-8 — 'UTF-8', после сброса пустой строкой — ''. Сравнение === различает эти случаи. Возвращённая PHP-строка принадлежит обычной PHP памяти; binding сам освобождает временный C-буфер.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$observed = $draw->getTextEncoding();
if ($observed !== 'UTF-8') {
$draw->setTextEncoding('UTF-8');
}
$draw->annotation(20, 65, 'Заказ № 42');
echo 'initial-encoding=', $observed === false ? 'unset' : ($observed === '' ? 'system-default' : $observed), '; effective=UTF-8', "\n";
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/explicit-encoding-policy.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'explicit-encoding-policy.png', "\n";
$image->clear();
Результат: explicit-encoding-policy.png 360×160. Видимая кириллическая подпись «Заказ № 42». В проверенной сборке исходная настройка false привела к явному выбору UTF-8. False — отсутствие заданной кодировки, а не повреждение файла или ошибка getter; исходные байты строки уже UTF-8. Перед именем файла консоль: initial-encoding=unset; effective=UTF-8. Последняя строка — explicit-encoding-policy.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Перенести явную UTF-8 политику и прочитать подпись из файла
Подпись поступает из приложенного label.txt. Прочитаем настройку темы, проверим реальные входные байты отдельно и применим ту же явную кодировку к новому Draw. Getter не может определить кодировку произвольного файла.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$theme = new ImagickDraw();
$theme->setTextEncoding('UTF-8');
$encoding = $theme->getTextEncoding();
if ($encoding !== 'UTF-8') {
throw new LogicException('Компоненту нужна явная UTF-8 политика');
}
$bytes = file_get_contents(__DIR__ . '/label.txt');
if ($bytes === false || preg_match('//u', $bytes) !== 1) {
throw new RuntimeException('Ожидался доступный UTF-8 файл label.txt');
}
$text = trim($bytes);
if ($text === '') {
throw new RuntimeException('Подпись не должна быть пустой');
}
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding($encoding);
$draw->annotation(20, 65, $text);
echo 'encoding=', $encoding, '; input=valid', "\n";
$theme->clear();
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/label-from-utf8-file.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'label-from-utf8-file.png', "\n";
$image->clear();
Результат: label-from-utf8-file.png 360×160. В PNG находится «Заказ № 42», прочитанный из настоящего label.txt архива. Сохранённый getter string использован setter другого объекта, а preg_match отдельно подтвердил корректную последовательность UTF-8. Перевод строки в конце файла убирает trim. Перед именем файла консоль: encoding=UTF-8; input=valid. Последняя строка — label-from-utf8-file.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Не делайте вывод «getter вернул UTF-8, значит вход уже корректен». Повреждённые или иной кодировки байты надо проверить/обработать отдельно до annotation. Наличие хороших UTF-8 байтов также не доказывает поддержку каждого символа конкретным font. Системный default не следует жёстко считать одной кодировкой на всех машинах.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::getTextDecoration · ImagickDraw::setTextDecoration · ImagickDraw::getTextUnderColor · ImagickDraw::setTextUnderColor · ImagickDraw::setTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
ImagickDraw::setTextEncodingРусская подпись из исходника или файла должна дать правильные буквы в PNG. Для этого нужны правильные байты, соответствующая настройка Draw и файл шрифта с нужными символами.
PECL imagick 2, PECL imagick 3 · imagick
ImagickDraw::setTextEncoding(string $encoding): boolРусская подпись из исходника или файла должна дать правильные буквы в PNG. Для этого нужны правильные байты, соответствующая настройка Draw и файл шрифта с нужными символами.
Официально поддерживается имя 'UTF-8' либо пустая строка для системного default. Setter записывает способ трактовки текста, а не выполняет конвертацию входа из Windows-1251/Latin-1. Наши исходники и label.txt уже UTF-8; неподходящие учебные байты отклоняются, после чего рисуется проверенная подпись.

Синтаксис, параметры и результат
ImagickDraw::setTextEncoding(string $encoding): bool| Параметр | Что передать и зачем |
|---|---|
| $encoding | string, обязательное 'UTF-8' в воспроизводимых примерах. '' сбрасывает к системному default; это не обещание одинакового результата на любой системе. Другие кодировки не преподносятся как поддержанные этим API. Не пытайтесь исправить mojibake сменой имени при уже испорченных байтах. |
bool по signature; текущий wrapper передаёт строку void DrawSetTextEncoding и возвращает true. Raw prose об отсутствии результата сохранено. True не подтверждает правильность исходных байтов, поддержку глифов или наличие готового PNG.
Официальная доступность: PECL imagick 2, PECL imagick 3. Deprecated, removed и changelog этой записи пусты; исходная отметка неполной документации сохранена. Примеры рассчитаны на PHP 8.2+ с imagick; фактически выполнены в PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 с приложенным шрифтом.
В кратких страницах отдельные ошибки описаны не полностью. Неизвестный enum, неверный цвет, недоступный font, неподходящие байты, ошибка drawImage и отказ записи PNG — разные условия; один успешный setter не проверяет весь процесс. Для собственных настроек выбирайте разрешённые именованные константы/цвета и явный договор входа. Ноль enum и false encoding getter не являются автоматической ошибкой выполнения.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->annotation(20, 65, 'Ёлка № 7');
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/utf8-cyrillic-label.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'utf8-cyrillic-label.png', "\n";
$image->clear();
Результат: utf8-cyrillic-label.png 360×160. Кириллическая надпись «Ёлка № 7» с буквой Ё и знаком №. Исходник сохранён в UTF-8, Draw получает UTF-8 и приложенный font содержит эти символы. Setter не создаёт нужные байты и не добавляет отсутствующие глифы. Последняя строка — utf8-cyrillic-label.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Практическая задача: Отклонить неподходящие байты и нарисовать проверенную подпись
Сервис договорился принимать UTF-8. Учебные legacy-байты не соответствуют этому договору: их нужно отклонить до рисования. Затем используем корректный файл label.txt. Установка имени UTF-8 сама не перекодирует Windows-1251 или Latin-1.
<?php
declare(strict_types=1);
$font = require __DIR__ . '/font.php';
$image = new Imagick();
$image->newImage(360, 160, 'white');
$image->setImageFormat('png');
$legacy = hex2bin('cff0e8e2e5f2');
if (preg_match('//u', $legacy) !== 1) {
echo 'invalid-input=rejected', "\n";
} else {
throw new LogicException('Учебные байты должны быть некорректным UTF-8');
}
$bytes = file_get_contents(__DIR__ . '/label.txt');
if ($bytes === false || preg_match('//u', $bytes) !== 1) {
throw new RuntimeException('Ожидался доступный UTF-8 файл label.txt');
}
$text = trim($bytes);
if ($text === '') {
throw new RuntimeException('Подпись не должна быть пустой');
}
$draw = new ImagickDraw();
$draw->setResolution(72, 72);
$draw->setFont($font);
$draw->setFontSize(24);
$draw->setStrokeColor('none');
$draw->setFillColor('#146c74');
$draw->setGravity(Imagick::GRAVITY_FORGET);
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
$draw->setTextAntialias(true);
$draw->setTextDecoration(Imagick::DECORATION_NO);
$draw->setTextUnderColor('none');
$draw->setTextEncoding('UTF-8');
$draw->annotation(20, 65, $text);
echo 'valid-input=rendered', "\n";
$image->drawImage($draw);
$draw->clear();
$path = __DIR__ . '/validated-utf8-input.png';
if (!$image->writeImage($path)) {
throw new RuntimeException('Не удалось сохранить PNG');
}
echo 'validated-utf8-input.png', "\n";
$image->clear();
Результат: validated-utf8-input.png 360×160. PNG содержит правильное «Заказ № 42» из label.txt; некорректная последовательность не попала в annotation. Это отказ по контракту входа, а не попытка угадать кодировку или тихо выбросить русские буквы. Преобразование известной исходной кодировки потребовало бы отдельной явной операции конвертации. Перед именем файла консоль: invalid-input=rejected; valid-input=rendered. Последняя строка — validated-utf8-input.png. Распакуйте архив целиком в отдельную папку и выполните php example.php при установленном PHP с imagick. PNG сохранится рядом с example.php: откройте его обычным просмотрщиком при 100%. Повторный запуск заменит одноимённый учебный файл. Font.php восстановит приложенный font.ttf без скачивания и установки.
Ошибки, альтернативы и стоимость
Не применяйте устаревшее utf8_decode как универсальный ремонт: оно меняет байты и не решает произвольную кириллицу. При известной иной исходной кодировке нужна отдельная корректная конвертация и проверка результата; в этой главе политика — принимать UTF-8 и явно отклонять неподходящие байты. HTTP Content-Type PNG описывает готовый файл, не заменяет кодировку PHP-строки. Setter не выбирает другой font и не создаёт отсутствующие emoji/иероглифы.
Настройки читаются отдельно от растеризации; основная работа с шрифтом и пикселями выполняется при рисовании. Ограничивайте размеры изображения и длину внешнего текста. Длинную строку сначала измеряют с тем же font/размером, затем выбирают перенос или сокращение; см. Imagick::queryFontMetrics. Для обычного текста на странице HTML/CSS удобнее заранее нарисованного PNG, если сам файл изображения не нужен.
Во вторых примерах $previous сохраняет настройку перед временным изменением, === различает false и строки, round округляет только диагностическую alpha. В файловом сценарии if (... !== 1) отказывает при неподходящих байтах, trim убирает завершающий перевод строки. Эти проверки не подменяют выбор подходящего шрифта.
Соседние настройки: ImagickDraw::getTextDecoration · ImagickDraw::setTextDecoration · ImagickDraw::getTextUnderColor · ImagickDraw::setTextUnderColor · ImagickDraw::getTextEncoding. Для отдельного бейджа используйте фигуры, для возврата состояния — очередь Draw.
Источники и обсуждения
- ImagickDraw::getTextDecoration
- ImagickDraw::getTextEncoding
- ImagickDraw::getTextUnderColor
- ImagickDraw::setTextDecoration
- ImagickDraw::setTextEncoding
- ImagickDraw::setTextUnderColor
- PHP ImagickDraw text wrappers
- DrawingWand text settings and Pixel copy
- Text rectangle and decoration rasterization
- PHP preg_match UTF-8 validation
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


