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

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

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

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

Глава 395 · После объектов, изображений и альфа-канала

Imagick: фон до чтения SVG и настоящая прозрачность PNG

Один логотип на трёх фонах, момент применения настройки, повторное чтение и функция экспорта с проверкой сохранённых файлов.

Получить прозрачный, белый и цветной PNG из одного логотипа

Для сайта нужен один логотип в трёх вариантах: прозрачный поверх любого блока страницы, на белом фоне для документа и на кремовом фоне для карточки. Исходник SVG хранит фигуры, а PNG — уже готовую сетку пикселей. Сначала зададим фон, затем прочитаем SVG и сохраним три настоящих файла. Размер каждого результата — 400×320.

Один SVG после чтения с transparent, white и #ffe8c2: три фактически сохранённых PNG; шахматная подложка показывает прозрачность только при просмотре
Один SVG после чтения с transparent, white и #ffe8c2: три фактически сохранённых PNG; шахматная подложка показывает прозрачность только при просмотре

В первом результате серо-белые клетки помогают увидеть прозрачную область. В first-transparent.png этих клеток нет: там прозрачность. Белый треугольник — часть логотипа, его удалять нельзя. Круг с половинной непрозрачностью показывает, как один и тот же цвет смешивается с разными фонами.

$image = new Imagick();
$image->setBackgroundColor("transparent");
$image->readImage(__DIR__ . "/logo.svg");
$image->setImageFormat("png32");
$image->writeImage(__DIR__ . "/logo.png");

Этот короткий пример работает, когда logo.svg лежит рядом с PHP-файлом. В скачиваемом архиве SVG хранится в logo.svg.b64 и автоматически восстанавливается при запуске полного example.php. new Imagick() создаёт объект ещё без изображения; $image сохраняет его. Стрелка -> вызывает действие этого объекта, скобки передают аргумент, точка с запятой заканчивает команду. Строка "transparent" означает прозрачный фон. В __DIR__ находится каталог PHP-файла, а точка . соединяет строки пути.

readImage читает файл, и именно в этот момент SVG превращается в пиксели. Поэтому настройка должна стоять перед чтением. png32 задаёт вариант PNG с четырьмя 8-битными каналами: красный, зелёный, синий и альфа. Альфа описывает непрозрачность: ноль — полностью прозрачный пиксель, максимум — полностью непрозрачный. writeImage сохраняет файл; сам вызов не выводит картинку в браузер. Откройте logo.png или поместите его в тег img. Нужны PHP с расширением Imagick, поддержка SVG и PNG и право записи в каталог.

В полном примере однажды прочитанный текст SVG передаётся readImageBlob: это тот же исходный документ в строке PHP. Для остальных вариантов меняется только аргумент фона. bgSave явно сохраняет PNG8 RGBA; bgView создаёт отдельную копию для показа на подложке. Начните с пяти строк выше, затем сравните три результата полного запуска.

Сохранить три PNG из одного SVG с разными фонами

Созданы три файла 400×320: прозрачный, с белым фоном и с кремовым #ffe8c2. Белый треугольник остаётся белым во всех вариантах. Полупрозрачный круг смешивается с выбранным фоном. Метод вернул true; строка цвета и ImagickPixel дали одинаковый результат до сохранения.

Сохранить три PNG из одного SVG с разными фонамиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
$transparent = new Imagick();
$returned = $transparent->setBackgroundColor('transparent');
$transparent->readImageBlob($svg);
$white = bgRender('white', $svg);
$color = bgRender('#ffe8c2', $svg);
$pixelColor = bgRender(new ImagickPixel('#ffe8c2'), $svg);
$default = new Imagick();
$default->readImageBlob($svg);
$saved = [
    'transparent'=>bgSave($transparent,'first-transparent.png'),
    'white'=>bgSave($white,'first-white.png'),
    'color'=>bgSave($color,'first-color.png'),
];
$t = new Imagick(__DIR__.'/first-transparent.png');
$w = new Imagick(__DIR__.'/first-white.png');
$c = new Imagick(__DIR__.'/first-color.png');
$views = [bgView($t), bgView($w), bgView($c)];
$images = ['transparent'=>bgImage($views[0],'first-transparent-view8.png'),'white'=>bgImage($views[1],'first-white-view8.png'),'color'=>bgImage($views[2],'first-color-view8.png')];
$rects = bgCompare($views,'read-background-first.png');
bgDiagnostic('read-background-first',[
 'executed_api'=>['setBackgroundColor'],'returned'=>$returned,'returned_type'=>get_debug_type($returned),'declared_return'=>(string)(new ReflectionMethod(Imagick::class,'setBackgroundColor'))->getReturnType(),
 'native'=>['transparent'=>bgState($transparent),'white'=>bgState($white),'color'=>bgState($color),'pixel_color'=>bgState($pixelColor),'default'=>bgState($default)],'saved'=>$saved,
 'images'=>$images,'panel_keys'=>['transparent','white','color'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['returned_true'=>$returned===true,'transparent_corner'=>$saved['transparent']['state']['corner'][3]===0,'white_corner'=>$saved['white']['state']['corner']===[65535,65535,65535,65535],'color_corner'=>$saved['color']['state']['corner']===[65535,59624,49858,65535],'partial_alpha'=>$saved['transparent']['state']['half'][3]>0&&$saved['transparent']['state']['half'][3]<65535,'white_shape_preserved'=>$saved['transparent']['state']['white_shape']===[65535,65535,65535,65535],'pixel_argument_equal'=>bgHash($pixelColor)===bgHash($color),'observed_default_white'=>bgHash($default)===bgHash($white),'geometry'=>$t->getImageGeometry()===['width'=>400,'height'=>320]]
]);
echo "read-background-first.png\nfirst-transparent-view8.png\nfirst-white-view8.png\nfirst-color-view8.png\nfirst-transparent.png\nfirst-white.png\nfirst-color.png\nmetrics.json\nreturned=true corner-alpha=0,65535,65535 white-shape=opaque\n";

Созданы три файла 400×320: прозрачный, с белым фоном и с кремовым #ffe8c2. Белый треугольник остаётся белым во всех вариантах. Полупрозрачный круг смешивается с выбранным фоном. Метод вернул true; строка цвета и ImagickPixel дали одинаковый результат до сохранения. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-first.png
first-transparent-view8.png
first-white-view8.png
first-color-view8.png
first-transparent.png
first-white.png
first-color.png
metrics.json
returned=true corner-alpha=0,65535,65535 white-shape=opaque

Понять момент чтения и отличие настройки от заливки

Прозрачный PNG и результат реального объединения с белым фоном: изменение свойства само по себе не равно изменению пикселей
Прозрачный PNG и результат реального объединения с белым фоном: изменение свойства само по себе не равно изменению пикселей

Последовательность состоит из четырёх разных шагов: $image получает настройку transparent → readImage читает logo.svg и строит RGBA-пиксели → writeImage кодирует PNG → новый Imagick читает сохранённый файл. После второго шага фон уже участвовал в рисовании. Поздняя настройка меняет правило объекта для дальнейших действий, но не возвращает исходные фигуры и не выполняет рисование заново.

ДействиеЧто происходит в этом примере
setBackgroundColor до чтения SVGВыбирается фон, который участвует в получении растра.
setBackgroundColor после чтенияТекущие RGBA-пиксели остаются прежними.
setImageBackgroundColor после чтенияИзменяется свойство фона текущего изображения. Пиксели пока прежние.
mergeImageLayers с LAYERMETHOD_FLATTENПолучается новое изображение с фактически добавленным фоном.
$image = new Imagick(__DIR__ . "/first-transparent.png");
$image->setImageBackgroundColor("white");
$flat = $image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$flat->writeImage(__DIR__ . "/white-logo.png");

Здесь файл уже существует, поэтому используется setImageBackgroundColor — настройка текущего изображения. Константа LAYERMETHOD_FLATTEN выбирает способ объединения. Возвращённый Imagick сохраняется в отдельную переменную $flat. Это полезно для экспорта прозрачного логотипа на конкретном фоне, например перед форматом, который не сохраняет альфу. Белый треугольник остаётся белым, потому что мы заполняем прозрачность, а не заменяем все белые пиксели.

Отличить изменение настройки от добавления настоящего фона

Поздний setBackgroundColor не изменил ранее полученные пиксели. setImageBackgroundColor на прозрачном изображении тоже только задал свойство. Реальное объединение с белым фоном выполнено mergeImageLayers; сохранённый minimal-flatten.png стал непрозрачным.

Отличить изменение настройки от добавления настоящего фонаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
$white = bgRender('white', $svg);
$beforeLate = bgState($white);
$white->setBackgroundColor('transparent');
$afterLate = bgState($white);
$transparent = bgRender('transparent', $svg);
$beforeImageSetting = bgState($transparent);
$transparent->setImageBackgroundColor('white');
$afterImageSetting = bgState($transparent);
$flattened = $transparent->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
$saved = ['before'=>bgSave($transparent,'minimal-before.png'),'flattened'=>bgSave($flattened,'minimal-flatten.png')];
$readBefore = new Imagick(__DIR__.'/minimal-before.png');
$readFlat = new Imagick(__DIR__.'/minimal-flatten.png');
$views = [bgView($readBefore), bgView($readFlat)];
$images = ['before'=>bgImage($views[0],'minimal-before-view8.png'),'flattened'=>bgImage($views[1],'minimal-flatten-view8.png')];
$rects = bgCompare($views,'read-background-minimal.png');
bgDiagnostic('read-background-minimal',[
 'executed_api'=>['setBackgroundColor'],'late'=>['before'=>$beforeLate,'after'=>$afterLate],'image_setting'=>['before'=>$beforeImageSetting,'after'=>$afterImageSetting],'flattened'=>bgState($flattened),'saved'=>$saved,
 'images'=>$images,'panel_keys'=>['before','flattened'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['late_pixels_unchanged'=>$beforeLate['RGBA16_sha256']===$afterLate['RGBA16_sha256'],'image_setting_pixels_unchanged'=>$beforeImageSetting['RGBA16_sha256']===$afterImageSetting['RGBA16_sha256'],'flatten_changes_pixels'=>bgHash($flattened)!==bgHash($transparent),'flatten_new_object'=>$flattened!==$transparent,'before_transparent'=>$saved['before']['state']['corner'][3]===0,'flatten_white'=>$saved['flattened']['state']['corner']===[65535,65535,65535,65535],'white_shape_preserved'=>$saved['before']['state']['white_shape']===$saved['flattened']['state']['white_shape']]
]);
echo "read-background-minimal.png\nminimal-before-view8.png\nminimal-flatten-view8.png\nminimal-before.png\nminimal-flatten.png\nmetrics.json\nlate-set=unchanged image-setting=unchanged flatten-alpha=65535\n";

Поздний setBackgroundColor не изменил ранее полученные пиксели. setImageBackgroundColor на прозрачном изображении тоже только задал свойство. Реальное объединение с белым фоном выполнено mergeImageLayers; сохранённый minimal-flatten.png стал непрозрачным. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-minimal.png
minimal-before-view8.png
minimal-flatten-view8.png
minimal-before.png
minimal-flatten.png
metrics.json
late-set=unchanged image-setting=unchanged flatten-alpha=65535

Разобрать повторное использование, белые фигуры и ошибки

Повторное чтение с прежним кремовым фоном, новый явно прозрачный объект и SVG с настоящим белым прямоугольником
Повторное чтение с прежним кремовым фоном, новый явно прозрачный объект и SVG с настоящим белым прямоугольником

При пакетной обработке один объект может пережить несколько файлов. Настройка принадлежит объекту и сохраняется, пока её не изменят. В проверке первое и второе чтение дали кремовый фон. Затем transparent задали явно, и третье чтение стало прозрачным. readImageBlob добавлял изображения в последовательность; setIteratorIndex выбирал нужный кадр с нумерацией от нуля. Для независимых экспортов проще создавать отдельный объект внутри функции.

Правая картинка показывает другую причину белого фона: в исходный SVG добавлен прямоугольник на весь холст. transparent задаёт пустую область под рисунком, но сам прямоугольник остаётся нарисованным. Нельзя механически удалять весь белый цвет: тогда исчезнет и полезный белый треугольник. В этом случае исправляют конкретную фоновую фигуру исходника или проектируют отдельное выделение объекта.

Проверить повторное чтение, нарисованный фон и ошибки цвета

Второе чтение тем же объектом использовало прежний кремовый фон. После явной настройки transparent третий кадр стал прозрачным. Новый объект настроен независимо. Сплошная белая фигура внутри другого SVG осталась видна, несмотря на transparent. Три ошибочных вызова перехвачены.

Проверить повторное чтение, нарисованный фон и ошибки цветаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
$reused = new Imagick();
$reused->setBackgroundColor('#ffe8c2');
$reused->readImageBlob($svg);
$reused->setIteratorIndex(0);
$firstState = bgState($reused);
$reused->readImageBlob($svg);
$reused->setIteratorIndex(1);
$secondState = bgState($reused);
$savedReused = bgSave($reused,'controls-reused.png');
$reused->setBackgroundColor('transparent');
$reused->readImageBlob($svg);
$reused->setIteratorIndex(2);
$thirdState = bgState($reused);
$fresh = bgRender('transparent', $svg);
$paintedSvg = str_replace('<rect x="60"','<rect width="400" height="320" fill="white"/><rect x="60"',$svg);
$painted = bgRender('transparent', $paintedSvg);
$saved = ['reused'=>$savedReused,'fresh'=>bgSave($fresh,'controls-fresh.png'),'painted'=>bgSave($painted,'controls-painted.png')];
$views = [bgView(new Imagick(__DIR__.'/controls-reused.png')),bgView(new Imagick(__DIR__.'/controls-fresh.png')),bgView(new Imagick(__DIR__.'/controls-painted.png'))];
$images = ['reused'=>bgImage($views[0],'controls-reused-view8.png'),'fresh'=>bgImage($views[1],'controls-fresh-view8.png'),'painted'=>bgImage($views[2],'controls-painted-view8.png')];
$rects = bgCompare($views,'read-background-controls.png');
$errors = [
 'invalid_color'=>bgTry(fn()=>(new Imagick())->setBackgroundColor('not-a-real-color-xyz')),
 'array'=>bgTry(fn()=>(new Imagick())->setBackgroundColor([])),
 'image_background_empty'=>bgTry(fn()=>(new Imagick())->setImageBackgroundColor('white')),
];
bgDiagnostic('read-background-controls',[
 'executed_api'=>['setBackgroundColor'],'reuse'=>['count'=>$reused->getNumberImages(),'first'=>$firstState,'second'=>$secondState,'third'=>$thirdState],'fresh'=>bgState($fresh),'painted'=>bgState($painted),'painted_svg_sha256'=>hash('sha256',$paintedSvg),'saved'=>$saved,'errors'=>$errors,
 'images'=>$images,'panel_keys'=>['reused','fresh','painted'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['three_images'=>$reused->getNumberImages()===3,'setting_reused'=>$firstState['RGBA16_sha256']===$secondState['RGBA16_sha256'],'explicit_change_applies_next'=>$thirdState['RGBA16_sha256']===bgHash($fresh),'paint_is_not_removed'=>$saved['painted']['state']['corner']===[65535,65535,65535,65535],'fresh_alpha'=>$saved['fresh']['state']['corner'][3]===0,'invalid_color_caught'=>($errors['invalid_color']['error']['class']??null)==='ImagickException','array_caught'=>($errors['array']['error']['class']??null)==='ImagickException','wrong_method_empty_caught'=>($errors['image_background_empty']['error']['class']??null)==='ImagickException']
]);
echo "read-background-controls.png\ncontrols-reused-view8.png\ncontrols-fresh-view8.png\ncontrols-painted-view8.png\ncontrols-reused.png\ncontrols-fresh.png\ncontrols-painted.png\nmetrics.json\nimages=3 reused=cream third=transparent painted=white errors=3\n";

Второе чтение тем же объектом использовало прежний кремовый фон. После явной настройки transparent третий кадр стал прозрачным. Новый объект настроен независимо. Сплошная белая фигура внутри другого SVG осталась видна, несмотря на transparent. Три ошибочных вызова перехвачены. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-controls.png
controls-reused-view8.png
controls-fresh-view8.png
controls-painted-view8.png
controls-reused.png
controls-fresh.png
controls-painted.png
metrics.json
images=3 reused=cream third=transparent painted=white errors=3
СимптомПроверка и действие
Вместо прозрачности белый прямоугольникПроверьте порядок вызовов и содержимое SVG: поздний setter и нарисованный фон — разные причины.
Второй экспорт получил фон первогоЗадайте фон явно для каждого чтения или создавайте новый объект.
Ошибка на новом ImagicksetBackgroundColor допустим до чтения; setImageBackgroundColor требует уже существующее изображение.
Unrecognized color stringИсправьте имя или HEX-строку цвета; пример перехватывает ImagickException.
Массив вместо цветаПередайте строку или ImagickPixel; смешивать цвет с массивом настроек нельзя.

Вынести экспорт в функцию и проверить сохранённые файлы

Два реальных результата функции: logo-web.png с альфой и logo-header.png с тёмным фоном #203e4a после повторного чтения
Два реальных результата функции: logo-web.png с альфой и logo-header.png с тёмным фоном #203e4a после повторного чтения

Когда один логотип нужен в нескольких местах сайта, повторяемый порядок удобно вынести в функцию exportLogo. Она получает текст SVG, цвет и имя результата. Внутри создаётся новый Imagick, цвет задаётся перед чтением, файл записывается и читается обратно. return возвращает сведения о результате; переменная $web сохраняет этот массив. Так параметры одного заказа не переходят в следующий.

$web = exportLogo($svg, "transparent", "logo-web.png");
$header = exportLogo($svg, "#203e4a", "logo-header.png");

Это вызовы функции, объявленной ниже в полном примере. logo-web.png можно положить поверх разных фонов страницы. В logo-header.png тёмный цвет уже записан в пиксели. export-report.json хранит имена, размеры и образцы значений после настоящего чтения файлов. Одна только смена setBackgroundColor на уже открытом logo-web.png не создаёт вариант для шапки: это отдельно проверено.

Выпустить логотип для сайта и для тёмной шапки

Функция создаёт отдельный объект для каждого результата: logo-web.png содержит настоящую прозрачность, logo-header.png — тёмный фон #203e4a. Оба файла и JSON-отчёт действительно прочитаны заново. Настройка фона на уже открытом PNG не перекрасила его.

Выпустить логотип для сайта и для тёмной шапкиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
function exportLogo(string $svg, string $background, string $filename): array
{
    $image = new Imagick();
    $image->setBackgroundColor($background);
    $image->readImageBlob($svg);
    $beforeSave = bgState($image);
    $saved = bgSave($image, $filename);
    $read = new Imagick(__DIR__ . '/' . $filename);
    return [
        'background' => $background,
        'before_save' => $beforeSave,
        'saved' => $saved,
        'readback' => bgState($read),
    ];
}

$web = exportLogo($svg, 'transparent', 'logo-web.png');
$header = exportLogo($svg, '#203e4a', 'logo-header.png');
$report = ['web' => $web, 'header' => $header];
file_put_contents(__DIR__ . '/export-report.json', json_encode(
    $report, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR
) . "\n");
$readReport = json_decode(
    (string) file_get_contents(__DIR__ . '/export-report.json'),
    true, 512, JSON_THROW_ON_ERROR
);
$webRead = new Imagick(__DIR__ . '/logo-web.png');
$headerRead = new Imagick(__DIR__ . '/logo-header.png');
$lateHeader = clone $webRead;
$lateHeader->setBackgroundColor('#203e4a');
$views = [bgView($webRead), bgView($headerRead)];
$images = ['web'=>bgImage($views[0],'workflow-web-view8.png'),'header'=>bgImage($views[1],'workflow-header-view8.png')];
$rects = bgCompare($views,'read-background-workflow.png');
bgDiagnostic('read-background-workflow',[
 'executed_api'=>['setBackgroundColor'],'report'=>$report,'read_report'=>$readReport,'late_PNG_setting'=>['before'=>bgState($webRead),'after'=>bgState($lateHeader)],
 'images'=>$images,'panel_keys'=>['web','header'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['web_alpha'=>$web['readback']['corner'][3]===0,'header_opaque'=>$header['readback']['corner']===[8224,15934,19018,65535],'report_readback'=>$report===$readReport,'actual_file_readback'=>$web['saved']['state']===$web['readback']&&$header['saved']['state']===$header['readback'],'white_shape_preserved'=>$web['readback']['white_shape']===[65535,65535,65535,65535],'same_geometry'=>$web['readback']['geometry']===$header['readback']['geometry'],'late_PNG_unchanged'=>bgHash($webRead)===bgHash($lateHeader)]
]);
echo "read-background-workflow.png\nworkflow-web-view8.png\nworkflow-header-view8.png\nlogo-web.png\nlogo-header.png\nexport-report.json\nmetrics.json\nweb-alpha=0 header-alpha=65535 report=read-back late-PNG=unchanged\n";

Функция создаёт отдельный объект для каждого результата: logo-web.png содержит настоящую прозрачность, logo-header.png — тёмный фон #203e4a. Оба файла и JSON-отчёт действительно прочитаны заново. Настройка фона на уже открытом PNG не перекрасила его. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-workflow.png
workflow-web-view8.png
workflow-header-view8.png
logo-web.png
logo-header.png
export-report.json
metrics.json
web-alpha=0 header-alpha=65535 report=read-back late-PNG=unchanged

В изображениях Q16 промежуточные каналы могут иметь более точные значения, чем 8-битный PNG. При сохранении возможна квантовка: поэтому отчёт показывает состояние до записи и фактическое состояние после чтения отдельно. Прозрачный угол и белая фигура проверяются по реальным файлам; равенство всех промежуточных чисел не обещается. Для этой задачи выбирается обычный PNG8 RGBA. Если нужны дополнительные разряды каналов, отдельно задайте формат сохранения и проверьте результат.

SVG в архиве собственный, небольшой и не требует шрифтов или внешних ресурсов. Поддержка сложного SVG зависит от сборки и обработчика; смена фона не восстанавливает потерянные градиенты, ссылки на изображения или шрифты. Чтение, растеризация и запись расходуют память и время в зависимости от размера, а сам setter лишь задаёт свойство. Для пользовательских файлов дополните этот приём правилами приёма файлов и обработкой ошибок.

Полный контракт, ограничения, упражнения и следующий шаг

Imagick::setBackgroundColor: полный контракт

Imagick::setBackgroundColor(mixed $background): bool

Метод устанавливает цвет фона по умолчанию для объекта Imagick. Единственный обязательный параметр background задаёт цвет; результат bool равен true при успешной установке. Это результат операции настройки, а не изображение. Изображение остаётся в $image, поэтому нельзя заменять его выражением $image = $image->setBackgroundColor("white").

В официальной сигнатуре сохранён тип mixed. Для понятного прикладного кода передавайте строку цвета, например "white", "#ffe8c2" или "transparent", либо объект new ImagickPixel("#ffe8c2"). Текущий stub Imagick 3.8.1 уточняет ImagickPixel|string. Строки поддерживаются с PECL imagick 2.1.0; раньше принимался только ImagickPixel. Доступность в принятом справочнике: PECL imagick 2, PECL imagick 3. Устаревшим метод не помечен.

На официальной странице отдельный раздел исключений отсутствует. В нашей реальной проверке Imagick 3.8.1 недопустимая строка цвета и массив вместо цвета вызвали ImagickException; это наблюдаемое поведение этой версии и её функции преобразования цвета. Установка допустимого фона на новый пустой Imagick успешна. Для setImageBackgroundColor пустой объект, напротив, дал ImagickException, потому что текущего изображения ещё нет.

В этой главе цвет применяется до чтения собственного SVG. Установка свойства после чтения сама по себе не перекрашивает существующие пиксели и не удаляет белые элементы рисунка. Для настоящей заливки прозрачности используйте операцию объединения с фоном; для уже нарисованной белой фигуры исправляйте исходный рисунок осмысленно. Поведение сложных SVG зависит также от установленного SVG-обработчика; установка фона не исправляет отсутствующие шрифты, внешние картинки или неподдержанный эффект.

Связанные действия: каналы и глубина цвета, размер и геометрия изображения и обработка исключений. Начальные понятия: объект и вызов метода.

Самостоятельный запуск и упражнение

Скачайте любой из четырёх архивов, распакуйте все файлы рядом и выполните php example.php. Входной SVG восстановится из base64, затем появятся названные PNG, metrics.json и, в последнем примере, export-report.json. Файлы с view8 в имени — только просмотры на шахматной подложке. PNG без view8 — настоящие результаты с альфой либо непрозрачным цветным фоном. Примеры проверены в PHP 8.5.11, Imagick 3.8.1 и ImageMagick 7.1.1-46 Q16.

Упражнение: нужен белый PNG из SVG, но код сначала вызывает new Imagick("logo.svg"), а затем setBackgroundColor("white"). Где ошибка порядка? Ответ: конструктор с путём уже прочитал SVG. Создайте пустой объект, задайте white и только затем прочитайте SVG. Если в распоряжении уже прозрачный PNG, настройте фон текущего изображения и выполните объединение, как во втором примере. Второе упражнение: после transparent белый треугольник остался. Это правильно: треугольник нарисован, а прозрачность относится к незакрашенным местам.

Полный вспомогательный PHP из каждого архива
<?php
declare(strict_types=1);
function bgRestore():void {
    $hashes=json_decode('{"logo.svg":"3f812bb3294b9dc9cd606008544395f3fcdef23e676a195f4f36930deaf048cd"}',true,512,JSON_THROW_ON_ERROR);
    foreach($hashes as $name=>$hash){$raw=base64_decode((string)file_get_contents(__DIR__.'/'.$name.'.b64'),true);if($raw===false||hash('sha256',$raw)!==$hash||file_put_contents(__DIR__.'/'.$name,$raw)===false)throw new RuntimeException('Input missing or changed');}
}
function bgHash(Imagick $i,string $map='RGBA',int $storage=Imagick::PIXEL_SHORT):string{return hash('sha256',json_encode($i->exportImagePixels(0,0,$i->getImageWidth(),$i->getImageHeight(),$map,$storage),JSON_THROW_ON_ERROR));}
function bgState(Imagick $i):array{return ['geometry'=>[$i->getImageWidth(),$i->getImageHeight()],'RGBA16_sha256'=>bgHash($i),'RGBA8_sha256'=>bgHash($i,'RGBA',Imagick::PIXEL_CHAR),'alpha_channel'=>$i->getImageAlphaChannel(),'corner'=>$i->exportImagePixels(0,0,1,1,'RGBA',Imagick::PIXEL_SHORT),'white_shape'=>$i->exportImagePixels(130,160,1,1,'RGBA',Imagick::PIXEL_SHORT),'half'=>$i->exportImagePixels(330,70,1,1,'RGBA',Imagick::PIXEL_SHORT)];}
function bgRender(string|ImagickPixel $color,string $svg):Imagick {$i=new Imagick();$i->setBackgroundColor($color);$i->readImageBlob($svg);return $i;}
function bgSave(Imagick $i,string $name,bool $preview=false):array {
    $c=clone $i;$c->setImageFormat('png');$c->setImageDepth(8);$c->setOption('png:bit-depth','8');$c->setOption('png:color-type',$preview?'2':'6');$c->setOption('png:exclude-chunk','all');
    if(!$c->writeImage(__DIR__.'/'.$name))throw new RuntimeException('Cannot save PNG');$read=new Imagick(__DIR__.'/'.$name);
    return ['filename'=>$name,'sha256'=>hash_file('sha256',__DIR__.'/'.$name),'bytes'=>filesize(__DIR__.'/'.$name),'state'=>bgState($read)];
}
function bgView(Imagick $i):Imagick {
    $v=new Imagick();$v->newImage(400,320,'white','png');$d=new ImagickDraw();$d->setStrokeAntialias(false);$d->setFillColor('#dde5e7');
    for($y=0;$y<320;$y+=20)for($x=0;$x<400;$x+=20)if((intdiv($x,20)+intdiv($y,20))%2===1)$d->rectangle($x,$y,$x+19,$y+19);
    $v->drawImage($d);$v->compositeImage($i,Imagick::COMPOSITE_OVER,0,0);return $v;
}
function bgImage(Imagick $view,string $name):array {$s=bgSave($view,$name,true);$r=new Imagick(__DIR__.'/'.$name);return ['geometry'=>[400,320],'RGB16_sha256'=>bgHash($view,'RGB'),'encoded_png'=>['filename'=>$name,'RGB16_sha256'=>bgHash($r,'RGB')],'display_basis'=>'Actual PNG readback composited over a display-only 20px white and #dde5e7 checkerboard'];}
function bgCompare(array $views,string $name):array {$i=new Imagick();$i->newImage(400*count($views),320,'white','png');$rects=[];foreach($views as $n=>$view){$i->compositeImage($view,Imagick::COMPOSITE_COPY,400*$n,0);$rects[]=['x'=>400*$n,'y'=>0,'width'=>400,'height'=>320];}bgSave($i,$name,true);return $rects;}
function bgTry(callable $f):array {try{$v=$f();return ['type'=>get_debug_type($v),'returned'=>$v];}catch(Throwable $e){return ['error'=>['class'=>get_class($e),'message'=>$e->getMessage()]];}}
function bgDiagnostic(string $id,array $data):void {$doc=['schema'=>'aen-read-background-program-diagnostics-v1','example_id'=>$id,'runtime'=>['php'=>PHP_VERSION,'imagick'=>phpversion('imagick'),'imagemagick'=>Imagick::getVersion()]]+$data;if(file_put_contents(__DIR__.'/metrics.json',json_encode($doc,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)."\n")===false)throw new RuntimeException('Cannot save metrics');}

bgRestore восстанавливает собственный SVG. bgSave отдельно сохраняет настоящие RGBA-файлы и непрозрачные просмотры. bgView рисует подложку только для показа. bgState читает реальные каналы, а bgDiagnostic сохраняет измерения. Эти функции помогают увидеть и проверить результат; порядок изучаемых вызовов остаётся в example.php.

Реальные вопросы разработчиков

Ниже — исходные ситуации из обсуждений. Технические выводы этой главы проверены по официальному описанию, исходникам и собственному запуску. Примеры и объяснения написаны заново; эти обсуждения не объявляются нормативной документацией.

ImageMagick Transparent PNG Background: После конвертации разработчик пытается удалить белый фон уже готового PNG. Разделяем прозрачный фон при чтении и уже нарисованные белые пиксели; сохраняем белый треугольник собственного логотипа.

Wrong white background when converting SVG to PNG with gradient: Фон SVG с градиентом становится белым, а настройка вызывается уже после чтения. На собственном SVG показываем настройку до чтения и неизменность пикселей после позднего setter; не обещаем этой настройкой исправить поддержку градиентов.

How to set transparent background of linked SVGs when convertig SVG to PNG using imageick: Внешние SVG, вложенные в другой документ, получают нежелательные белые области. Объясняем границу настройки: собственная нарисованная белая фигура не удаляется transparent, а вложенные ресурсы и SVG-обработчик требуют отдельной проверки.

PHP IMAGICK - Conversion from SVG to PNG results in broken images: При SVG-конвертации путают setImageBackgroundColor и настройку ещё пустого объекта; результат отличается от исходника. Проверяем ошибку метода текущего изображения на пустом объекте и показываем правильный порядок setBackgroundColor до чтения.

How can I add a background to my png image?: Нужен один PNG-аватар с разными цветами фона вместо ручной подготовки множества файлов. Вводим реальное объединение прозрачного PNG с белым фоном и отдельную функцию экспорта логотипа в разные варианты.

ImageMagick SVG to PNG conversions removes gradients: PNG для CMS теряет градиенты SVG; конструктор уже прочитал файл до установки фона. Показываем пустой объект и явный порядок настройки/чтения; отдельно обозначаем зависимость сложного SVG от обработчика и не выдаём фон за универсальное исправление эффектов.

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

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

Imagick::setBackgroundColorЗадать фон перед чтением SVG и сохранить прозрачный или цветной PNG

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setBackgroundColor(mixed $background): bool

Imagick::setBackgroundColor: полный контракт

Imagick::setBackgroundColor(mixed $background): bool

Метод устанавливает цвет фона по умолчанию для объекта Imagick. Единственный обязательный параметр background задаёт цвет; результат bool равен true при успешной установке. Это результат операции настройки, а не изображение. Изображение остаётся в $image, поэтому нельзя заменять его выражением $image = $image->setBackgroundColor("white").

В официальной сигнатуре сохранён тип mixed. Для понятного прикладного кода передавайте строку цвета, например "white", "#ffe8c2" или "transparent", либо объект new ImagickPixel("#ffe8c2"). Текущий stub Imagick 3.8.1 уточняет ImagickPixel|string. Строки поддерживаются с PECL imagick 2.1.0; раньше принимался только ImagickPixel. Доступность в принятом справочнике: PECL imagick 2, PECL imagick 3. Устаревшим метод не помечен.

На официальной странице отдельный раздел исключений отсутствует. В нашей реальной проверке Imagick 3.8.1 недопустимая строка цвета и массив вместо цвета вызвали ImagickException; это наблюдаемое поведение этой версии и её функции преобразования цвета. Установка допустимого фона на новый пустой Imagick успешна. Для setImageBackgroundColor пустой объект, напротив, дал ImagickException, потому что текущего изображения ещё нет.

В этой главе цвет применяется до чтения собственного SVG. Установка свойства после чтения сама по себе не перекрашивает существующие пиксели и не удаляет белые элементы рисунка. Для настоящей заливки прозрачности используйте операцию объединения с фоном; для уже нарисованной белой фигуры исправляйте исходный рисунок осмысленно. Поведение сложных SVG зависит также от установленного SVG-обработчика; установка фона не исправляет отсутствующие шрифты, внешние картинки или неподдержанный эффект.

Связанные действия: каналы и глубина цвета, размер и геометрия изображения и обработка исключений. Начальные понятия: объект и вызов метода.

Сохранить три PNG из одного SVG с разными фонами

Созданы три файла 400×320: прозрачный, с белым фоном и с кремовым #ffe8c2. Белый треугольник остаётся белым во всех вариантах. Полупрозрачный круг смешивается с выбранным фоном. Метод вернул true; строка цвета и ImagickPixel дали одинаковый результат до сохранения.

Сохранить три PNG из одного SVG с разными фонамиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
$transparent = new Imagick();
$returned = $transparent->setBackgroundColor('transparent');
$transparent->readImageBlob($svg);
$white = bgRender('white', $svg);
$color = bgRender('#ffe8c2', $svg);
$pixelColor = bgRender(new ImagickPixel('#ffe8c2'), $svg);
$default = new Imagick();
$default->readImageBlob($svg);
$saved = [
    'transparent'=>bgSave($transparent,'first-transparent.png'),
    'white'=>bgSave($white,'first-white.png'),
    'color'=>bgSave($color,'first-color.png'),
];
$t = new Imagick(__DIR__.'/first-transparent.png');
$w = new Imagick(__DIR__.'/first-white.png');
$c = new Imagick(__DIR__.'/first-color.png');
$views = [bgView($t), bgView($w), bgView($c)];
$images = ['transparent'=>bgImage($views[0],'first-transparent-view8.png'),'white'=>bgImage($views[1],'first-white-view8.png'),'color'=>bgImage($views[2],'first-color-view8.png')];
$rects = bgCompare($views,'read-background-first.png');
bgDiagnostic('read-background-first',[
 'executed_api'=>['setBackgroundColor'],'returned'=>$returned,'returned_type'=>get_debug_type($returned),'declared_return'=>(string)(new ReflectionMethod(Imagick::class,'setBackgroundColor'))->getReturnType(),
 'native'=>['transparent'=>bgState($transparent),'white'=>bgState($white),'color'=>bgState($color),'pixel_color'=>bgState($pixelColor),'default'=>bgState($default)],'saved'=>$saved,
 'images'=>$images,'panel_keys'=>['transparent','white','color'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['returned_true'=>$returned===true,'transparent_corner'=>$saved['transparent']['state']['corner'][3]===0,'white_corner'=>$saved['white']['state']['corner']===[65535,65535,65535,65535],'color_corner'=>$saved['color']['state']['corner']===[65535,59624,49858,65535],'partial_alpha'=>$saved['transparent']['state']['half'][3]>0&&$saved['transparent']['state']['half'][3]<65535,'white_shape_preserved'=>$saved['transparent']['state']['white_shape']===[65535,65535,65535,65535],'pixel_argument_equal'=>bgHash($pixelColor)===bgHash($color),'observed_default_white'=>bgHash($default)===bgHash($white),'geometry'=>$t->getImageGeometry()===['width'=>400,'height'=>320]]
]);
echo "read-background-first.png\nfirst-transparent-view8.png\nfirst-white-view8.png\nfirst-color-view8.png\nfirst-transparent.png\nfirst-white.png\nfirst-color.png\nmetrics.json\nreturned=true corner-alpha=0,65535,65535 white-shape=opaque\n";

Созданы три файла 400×320: прозрачный, с белым фоном и с кремовым #ffe8c2. Белый треугольник остаётся белым во всех вариантах. Полупрозрачный круг смешивается с выбранным фоном. Метод вернул true; строка цвета и ImagickPixel дали одинаковый результат до сохранения. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-first.png
first-transparent-view8.png
first-white-view8.png
first-color-view8.png
first-transparent.png
first-white.png
first-color.png
metrics.json
returned=true corner-alpha=0,65535,65535 white-shape=opaque

Выпустить логотип для сайта и для тёмной шапки

Функция создаёт отдельный объект для каждого результата: logo-web.png содержит настоящую прозрачность, logo-header.png — тёмный фон #203e4a. Оба файла и JSON-отчёт действительно прочитаны заново. Настройка фона на уже открытом PNG не перекрасила его.

Выпустить логотип для сайта и для тёмной шапкиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/background-fixture.php';
bgRestore();
$svg=(string)file_get_contents(__DIR__.'/logo.svg');
$sourceHash=hash('sha256',$svg);
function exportLogo(string $svg, string $background, string $filename): array
{
    $image = new Imagick();
    $image->setBackgroundColor($background);
    $image->readImageBlob($svg);
    $beforeSave = bgState($image);
    $saved = bgSave($image, $filename);
    $read = new Imagick(__DIR__ . '/' . $filename);
    return [
        'background' => $background,
        'before_save' => $beforeSave,
        'saved' => $saved,
        'readback' => bgState($read),
    ];
}

$web = exportLogo($svg, 'transparent', 'logo-web.png');
$header = exportLogo($svg, '#203e4a', 'logo-header.png');
$report = ['web' => $web, 'header' => $header];
file_put_contents(__DIR__ . '/export-report.json', json_encode(
    $report, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR
) . "\n");
$readReport = json_decode(
    (string) file_get_contents(__DIR__ . '/export-report.json'),
    true, 512, JSON_THROW_ON_ERROR
);
$webRead = new Imagick(__DIR__ . '/logo-web.png');
$headerRead = new Imagick(__DIR__ . '/logo-header.png');
$lateHeader = clone $webRead;
$lateHeader->setBackgroundColor('#203e4a');
$views = [bgView($webRead), bgView($headerRead)];
$images = ['web'=>bgImage($views[0],'workflow-web-view8.png'),'header'=>bgImage($views[1],'workflow-header-view8.png')];
$rects = bgCompare($views,'read-background-workflow.png');
bgDiagnostic('read-background-workflow',[
 'executed_api'=>['setBackgroundColor'],'report'=>$report,'read_report'=>$readReport,'late_PNG_setting'=>['before'=>bgState($webRead),'after'=>bgState($lateHeader)],
 'images'=>$images,'panel_keys'=>['web','header'],'panel_geometry'=>$rects,'source_sha256'=>$sourceHash,'source_unchanged'=>hash_file('sha256',__DIR__.'/logo.svg')===$sourceHash,
 'checks'=>['web_alpha'=>$web['readback']['corner'][3]===0,'header_opaque'=>$header['readback']['corner']===[8224,15934,19018,65535],'report_readback'=>$report===$readReport,'actual_file_readback'=>$web['saved']['state']===$web['readback']&&$header['saved']['state']===$header['readback'],'white_shape_preserved'=>$web['readback']['white_shape']===[65535,65535,65535,65535],'same_geometry'=>$web['readback']['geometry']===$header['readback']['geometry'],'late_PNG_unchanged'=>bgHash($webRead)===bgHash($lateHeader)]
]);
echo "read-background-workflow.png\nworkflow-web-view8.png\nworkflow-header-view8.png\nlogo-web.png\nlogo-header.png\nexport-report.json\nmetrics.json\nweb-alpha=0 header-alpha=65535 report=read-back late-PNG=unchanged\n";

Функция создаёт отдельный объект для каждого результата: logo-web.png содержит настоящую прозрачность, logo-header.png — тёмный фон #203e4a. Оба файла и JSON-отчёт действительно прочитаны заново. Настройка фона на уже открытом PNG не перекрасила его. Архив содержит example.php, logo.svg.b64 и background-fixture.php. Распакуйте их рядом и выполните php example.php: SVG восстановится автоматически. Методы изучаемой библиотеки вызываются в основном файле; helper сохраняет результаты, строит просмотры и записывает измерения. Полный helper приведён в конце главы. Проверено в PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16, Windows.

Ожидаемый вывод после настоящего запуска
read-background-workflow.png
workflow-web-view8.png
workflow-header-view8.png
logo-web.png
logo-header.png
export-report.json
metrics.json
web-alpha=0 header-alpha=65535 report=read-back late-PNG=unchanged
Источники и обсуждения

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

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

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

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