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

Дерево руководства
Глава 435 · После первых изображений, цветов GmagickPixel и наложения OVER
Gmagick: прозрачность, matte color и реальный фон
Проверить фактическую прозрачность, отличить её от свойства цвета, сохранить небольшой логотип и подготовить карточку на выбранном фоне.
Увидеть прозрачность на клетчатой подложке
Продолжаем цвета и компоненты пикселя и наложение изображений. Здесь слова «alpha», «matte channel» и «matte color» описывают разные вещи. Alpha — значение прозрачности каждого пикселя; matte channel — старое название соответствующего канала; matte color — одно цветовое свойство изображения. Модель листа с пустыми местами помогает представить наложение, но файл хранит числа, а не физические отверстия.
Прозрачный логотип должен одинаково пригодиться для светлой страницы, тёмной темы и карточки товара. На обычном белом фоне трудно понять, где в файле белая краска, а где пустое место. Поэтому сначала положим его на клетчатую подложку и сохраним исходный прозрачный PNG отдельно.



<?php
$logo = new Gmagick(__DIR__ . '/logo.png');
$preview = new Gmagick(__DIR__ . '/checker.ppm');
$preview->compositeImage($logo, Gmagick::COMPOSITE_OVER, 0, 0);
$preview->setImageFormat('PNG');
$preview->writeImage(__DIR__ . '/preview.png');new создаёт объект и читает указанный файл. Переменные $logo и $preview относятся к разным изображениям. Стрелка -> вызывает метод у объекта слева. compositeImage накладывает $logo на $preview; OVER учитывает прозрачность верхнего слоя, а два нуля задают его положение от левого верхнего угла. На выходе preview.png содержит нарисованные клетки, а исходный logo.png сохраняет пустые области.
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$logo = new Gmagick(__DIR__ . '/logo.png');
$matteAvailable = method_exists($logo, 'getImageMatte');
$matteChannel = $matteAvailable ? $logo->getImageMatte() : null;
$hasTransparentPixels = false;
foreach ($logo->getImageHistogram() as $pixel) {
if ($pixel->getColorValue(Gmagick::COLOR_OPACITY) > 0.0) {
$hasTransparentPixels = true;
break;
}
}
$checker = new Gmagick(__DIR__ . '/checker.ppm');
$checker->compositeImage($logo, Gmagick::COMPOSITE_OVER, 0, 0);
$logo->setImageDepth(8);
$logo->setImageFormat('PNG');
$logo->writeImage(__DIR__ . '/gm101-logo-copy.png');
$checker->setImageDepth(8);
$checker->setImageFormat('PNG');
$checker->writeImage(__DIR__ . '/gm101-logo-checker.png');
$opaque = new Gmagick(__DIR__ . '/product.ppm');
$opaque->setImageType(Gmagick::IMGTYPE_TRUECOLORMATTE);
$opaque->setImageDepth(8);
$opaque->setImageFormat('PNG');
$opaque->writeImage(__DIR__ . '/gm101-opaque-rgba.png');
$opaqueRead = new Gmagick(__DIR__ . '/gm101-opaque-rgba.png');
$allOpaque = true;
foreach ($opaqueRead->getImageHistogram() as $pixel) {
if ($pixel->getColorValue(Gmagick::COLOR_OPACITY) > 0.0) $allOpaque = false;
}
$pngBytes = file_get_contents(__DIR__ . '/gm101-opaque-rgba.png');
$pngColorType = ord($pngBytes[25]); // IHDR color type: 6 is RGBA.
gmReport('gm101-alpha-visible',["gmagick.construct", "gmagick.getimagehistogram", "gmagickpixel.getcolorvalue", "gmagick.compositeimage", "gmagick.setimagedepth", "gmagick.setimageformat", "gmagick.writeimage", "gmagick.setimagetype"],["gm101-logo-copy.png", "gm101-logo-checker.png", "gm101-opaque-rgba.png"],
['guarded_method_unavailable'=>$matteAvailable === false && $matteChannel === null,'actual_transparency'=>$hasTransparentPixels,'opaque_alpha_channel'=>$allOpaque && $pngColorType === 6,'size_gm101_logo_copy'=>gmInspect('gm101-logo-copy.png')['width'] === 320 && gmInspect('gm101-logo-copy.png')['height'] === 200,'size_gm101_logo_checker'=>gmInspect('gm101-logo-checker.png')['width'] === 320 && gmInspect('gm101-logo-checker.png')['height'] === 200,'size_gm101_opaque_rgba'=>gmInspect('gm101-opaque-rgba.png')['width'] === 320 && gmInspect('gm101-opaque-rgba.png')['height'] === 200],
$errors ?? [], ['matte_method_available' => $matteAvailable, 'availability_path' => 'guarded_fallback', 'alternative_executed' => true, 'has_transparent_pixels' => $hasTransparentPixels, 'opaque_png_color_type' => $pngColorType]);
echo "gm101-logo-copy.png 320x200\ngm101-logo-checker.png 320x200\ngm101-opaque-rgba.png 320x200\n";
Ожидаемый результат
gm101-logo-copy.png 320x200
gm101-logo-checker.png 320x200
gm101-opaque-rgba.png 320x200
Запуск: php example.php с Gmagick. Проверенная среда: PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16. Архив содержит точные собственные входы в .b64; gm-fixture.php восстанавливает их и записывает проверочные metrics.json. Изучаемые операции находятся в программе. Исходный logo.png остаётся прозрачным и неизменным.
Название «matte channel» в старом API относится к каналу прозрачности. Наличие такого канала ещё не доказывает, что какой-то пиксель прозрачен. Третья картинка специально записана как RGBA, но все её значения alpha равны 255. Наш запасной путь проверяет фактические пиксели, а не наличие места под канал: это связанный, но другой вопрос.
В исходном RGBA8-файле alpha = 0 означает полную прозрачность, 255 — полную непрозрачность. У нашего белого участка alpha = 64, около 25% непрозрачности. Константа Gmagick::COLOR_OPACITY при чтении GmagickPixel в проверенной библиотеке использует обратное направление: 0 — непрозрачно, 1 — прозрачно; для этого участка получилось 191/255. Нельзя переносить число из одного представления в другое без уточнения смысла.
| Что проверяем | Что получаем | Чего этого недостаточно доказать |
|---|---|---|
| getImageMatte() при наличии метода | Признак наличия канала | Есть ли хотя бы один прозрачный пиксель |
| getImageMatteColor() | GmagickPixel со значением свойства | Как выглядит изображение на выбранном фоне |
| Гистограмма и COLOR_OPACITY | Есть ли реально прозрачные значения | Структурное наличие канала с полностью непрозрачными значениями |
| Наложение OVER на отдельный холст | Пиксели готовой карточки | Сохранность прозрачного оригинала, если его перезаписать |
В установленной сборке getImageMatte отсутствует. Доступность проверяется до вызова; полный пример не падает и не притворяется, что выполнил этот getter. Запасная проверка просматривает цвета гистограммы и отвечает на другой полезный вопрос: есть ли фактическая прозрачность. Одной точки в углу для такого вывода обо всём изображении недостаточно.
<?php
$logo = new Gmagick(__DIR__ . '/logo.png');
if (method_exists($logo, 'getImageMatte')) {
$hasChannel = $logo->getImageMatte();
} else {
$hasChannel = null; // Метод недоступен, результат неизвестен.
}Каждый ZIP сам восстанавливает logo.png, checker.ppm и product.ppm из точных .b64-данных. Помощник занимается только входными файлами и проверочными метриками; он не подменяет наложение и другие изучаемые действия. Короткие фрагменты предполагают эти файлы рядом с PHP. Логотип создан нативными командами GmagickDraw, затем сохранён как исходник; альфа 64 получена из настоящего PNG. Клетки нарисованы в отдельном PPM и входят только в проверочные превью. Для повторного использования нужен прозрачный logo.png, а не картинка с уже нарисованными клетками.
Проверить, закрашивает ли matte color прозрачные места
Допустим, для карточки выбран янтарный фирменный фон. Попробуем назначить его свойству matte color и проверим результат. Две настройки цвета читаются правильно, однако прозрачные места остаются прозрачными и клетки всё ещё видны.




<?php
$logo = new Gmagick(__DIR__ . '/logo.png');
$ok = $logo->setImageMatteColor('#e5a74a');
$pixel = $logo->getImageMatteColor();
$rgb = $pixel->getColor(true);
echo $rgb['r'], ',', $rgb['g'], ',', $rgb['b'], "\n";Ожидаемый вывод — 229,167,74. Строка #e5a74a задаёт цвет. getImageMatteColor возвращает GmagickPixel — объект цвета; getColor(true) читает массив с компонентами r, g и b. Квадратные скобки выбирают значение по ключу. Setter в проверенной сборке возвращает bool true, поэтому следующую операцию вызываем у $logo, а не строим цепочку из результата setter.
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$amber = new Gmagick(__DIR__ . '/logo.png');
$before = $amber->getImageSignature();
$amberResult = $amber->setImageMatteColor('#e5a74a');
$amberRgb = $amber->getImageMatteColor()->getColor(true);
$blue = new Gmagick(__DIR__ . '/logo.png');
$blueResult = $blue->setImageMatteColor(new GmagickPixel('#244f65'));
$blueRgb = $blue->getImageMatteColor()->getColor(true);
$unchanged = $before === $amber->getImageSignature()
&& $before === $blue->getImageSignature();
$checker = new Gmagick(__DIR__ . '/checker.ppm');
$checker->compositeImage($amber, Gmagick::COMPOSITE_OVER, 0, 0);
$amber->setImageDepth(8);
$amber->setImageFormat('PNG');
$amber->writeImage(__DIR__ . '/gm101-matte-amber.png');
$blue->setImageDepth(8);
$blue->setImageFormat('PNG');
$blue->writeImage(__DIR__ . '/gm101-matte-blue.png');
$checker->setImageDepth(8);
$checker->setImageFormat('PNG');
$checker->writeImage(__DIR__ . '/gm101-matte-checker.png');
gmReport('gm101-alpha-setting',["gmagickpixel.construct", "gmagick.construct", "gmagick.getimagesignature", "gmagick.setimagemattecolor", "gmagick.getimagemattecolor", "gmagickpixel.getcolor", "gmagick.compositeimage", "gmagick.setimagedepth", "gmagick.setimageformat", "gmagick.writeimage"],["gm101-matte-amber.png", "gm101-matte-blue.png", "gm101-matte-checker.png"],
['setter_bool'=>$amberResult === true && $blueResult === true,'getter_colors'=>$amberRgb === ['r'=>229,'g'=>167,'b'=>74] && $blueRgb === ['r'=>36,'g'=>79,'b'=>101],'pixels_unchanged'=>$unchanged,'size_gm101_matte_amber'=>gmInspect('gm101-matte-amber.png')['width'] === 320 && gmInspect('gm101-matte-amber.png')['height'] === 200,'size_gm101_matte_blue'=>gmInspect('gm101-matte-blue.png')['width'] === 320 && gmInspect('gm101-matte-blue.png')['height'] === 200,'size_gm101_matte_checker'=>gmInspect('gm101-matte-checker.png')['width'] === 320 && gmInspect('gm101-matte-checker.png')['height'] === 200],
$errors ?? [], ['amber_rgb' => $amberRgb, 'blue_rgb' => $blueRgb, 'setter_returns_bool' => true, 'unchanged_pixel_signature' => $unchanged]);
echo "gm101-matte-amber.png 320x200\ngm101-matte-blue.png 320x200\ngm101-matte-checker.png 320x200\n";
Ожидаемый результат
gm101-matte-amber.png 320x200
gm101-matte-blue.png 320x200
gm101-matte-checker.png 320x200
Запуск: php example.php с Gmagick. Проверенная среда: PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16. Архив содержит точные собственные входы в .b64; gm-fixture.php восстанавливает их и записывает проверочные metrics.json. Изучаемые операции находятся в программе. Исходный logo.png остаётся прозрачным и неизменным.
Полная программа сравнивает подпись пикселей до и после двух назначений: она осталась прежней. Само свойство matte color не является командой заменить прозрачность цветом. Чтобы получить реальные фоновые пиксели, дальше создадим отдельный холст и выполним наложение. Полученный объект цвета также нельзя напрямую считать одним пикселем изображения: это значение свойства.
Дополнительный setter этой сборки
setImageMatteColor не имеет отдельной страницы в текущем официальном PHP Manual и не включён здесь в число новых официальных карточек. Он присутствует в исследованной сборке и в исходниках расширения. Перед переносом кода в другое окружение проверьте method_exists($logo, "setImageMatteColor").
Gmagick::setImageMatteColor($color): boolОдин обязательный аргумент: строка распознаваемого цвета или GmagickPixel. Исходник обёртки разбирает это как цвет; проверены оба варианта. Возврат в нашей сборке — true, не Gmagick. У пустого объекта операция даёт GmagickException, неизвестная строка цвета даёт GmagickPixelException, массив — GmagickException. Назначается свойство matte color; переносить это описание на изменение всех alpha-пикселей нельзя.
getColor() без true в этой Q16-сборке возвращает строку с квантовыми значениями. Для нового холста мы явно собираем обычный RGB8 через getColor(true) и sprintf. Объект GmagickPixel и массив RGB подробнее разобраны в уроке о цвете.
Получить светлую и тёмную карточку с реальным фоном
Для светлой и тёмной темы нужны две действительно разные карточки. Воспользуемся выбранным matte color как настройкой приложения: прочитаем её, создадим холст такого цвета и наложим логотип. Теперь прозрачные места заполнены фоном, а полупрозрачная полоса смешивается с ним.



<?php
$logo = new Gmagick(__DIR__ . '/logo.png');
$canvas = new Gmagick();
$canvas->newImage(320, 200, '#18222b', 'png');
$canvas->compositeImage($logo, Gmagick::COMPOSITE_OVER, 0, 0);
$canvas->writeImage(__DIR__ . '/dark-card.png');newImage принимает ширину и высоту в пикселях, цвет и формат. Этот вызов действительно создаёт фон. Затем compositeImage изменяет его пиксели с учётом alpha логотипа. В полной программе цвет приходит из getImageMatteColor: sprintf превращает три числа RGB8 в строку #RRGGBB; %02x означает две шестнадцатеричные цифры с ведущим нулём. Так сохранённая настройка становится явным входом операции.
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$logo = new Gmagick(__DIR__ . '/logo.png');
$colors = [];
foreach (['light' => '#f8f8f8', 'dark' => '#18222b'] as $name => $requested) {
$logo->setImageMatteColor($requested);
$rgb = $logo->getImageMatteColor()->getColor(true);
$colors[$name] = $rgb;
$css = sprintf('#%02x%02x%02x', $rgb['r'], $rgb['g'], $rgb['b']);
$canvas = new Gmagick();
$canvas->newImage(320, 200, $css, 'png');
$canvas->compositeImage($logo, Gmagick::COMPOSITE_OVER, 0, 0);
$canvas->setImageDepth(8);
$canvas->setImageFormat('PNG');
$canvas->writeImage(__DIR__ . '/gm101-' . $name . '-card.png');
}
gmReport('gm101-alpha-backgrounds',["gmagick.construct", "gmagick.setimagemattecolor", "gmagick.getimagemattecolor", "gmagickpixel.getcolor", "gmagick.newimage", "gmagick.compositeimage", "gmagick.setimagedepth", "gmagick.setimageformat", "gmagick.writeimage"],["gm101-light-card.png", "gm101-dark-card.png"],
['theme_colors'=>$colors['light'] === ['r'=>248,'g'=>248,'b'=>248] && $colors['dark'] === ['r'=>24,'g'=>34,'b'=>43],'size_gm101_light_card'=>gmInspect('gm101-light-card.png')['width'] === 320 && gmInspect('gm101-light-card.png')['height'] === 200,'size_gm101_dark_card'=>gmInspect('gm101-dark-card.png')['width'] === 320 && gmInspect('gm101-dark-card.png')['height'] === 200],
$errors ?? [], ['background_colors' => $colors, 'background_applied_by' => 'newImage + compositeImage OVER']);
echo "gm101-light-card.png 320x200\ngm101-dark-card.png 320x200\n";
Ожидаемый результат
gm101-light-card.png 320x200
gm101-dark-card.png 320x200
Запуск: php example.php с Gmagick. Проверенная среда: PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16. Архив содержит точные собственные входы в .b64; gm-fixture.php восстанавливает их и записывает проверочные metrics.json. Изучаемые операции находятся в программе. Исходный logo.png остаётся прозрачным и неизменным.
У прозрачного угла исходника alpha равна 0, поэтому здесь полностью виден фон. У синей эмблемы alpha равна 255, её цвет остаётся прежним. У белой полосы вне эмблемы alpha равна 64 из 255: на тёмном фоне её RGB стал 81,89,96, а на светлом — 249,249,249. Это реальные значения сохранённых файлов; прозрачность нельзя оценивать по одному названию цвета.
Уменьшить логотип, сохранив прозрачность
В маленькой карточке нужен логотип шириной 160 пикселей, который ещё можно положить на любой фон. Уменьшим изображение, сохраним прозрачный результат, а для проверки сделаем отдельный вариант на клетках. Настройка matte color не должна неожиданно превращаться в фон при сохранении.



<?php
$preview = new Gmagick(__DIR__ . '/logo.png');
$preview->thumbnailImage(160, 100, true);
$preview->setImageMatteColor('#f8f8f8');
$preview->setImageFormat('PNG');
$preview->writeImage(__DIR__ . '/small-logo.png');thumbnailImage ограничивает размер рамкой 160 × 100 и при true сохраняет пропорции. Наш исходник 320 × 200 уменьшается вдвое по обеим осям. Назначение matte color сделано после изменения размера. Полная программа повторно открывает полученный PNG и проверяет наличие реально прозрачных пикселей; это проверка результата записи, а не предположение о настройке объекта.
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$preview = new Gmagick(__DIR__ . '/logo.png');
$preview->thumbnailImage(160, 100, true);
$preview->setImageMatteColor('#f8f8f8');
$matteAvailable = method_exists($preview, 'getImageMatte');
$matteChannel = $matteAvailable ? $preview->getImageMatte() : null;
$preview->setImageDepth(8);
$preview->setImageFormat('PNG');
$preview->writeImage(__DIR__ . '/gm101-small-logo.png');
$decoded = new Gmagick(__DIR__ . '/gm101-small-logo.png');
$hasTransparency = false;
foreach ($decoded->getImageHistogram() as $pixel) {
if ($pixel->getColorValue(Gmagick::COLOR_OPACITY) > 0.0) {
$hasTransparency = true;
break;
}
}
$checker = new Gmagick(__DIR__ . '/checker.ppm');
$checker->resizeImage(160, 100, Gmagick::FILTER_POINT, 1.0, false);
$checker->compositeImage($preview, Gmagick::COMPOSITE_OVER, 0, 0);
$checker->setImageDepth(8);
$checker->setImageFormat('PNG');
$checker->writeImage(__DIR__ . '/gm101-small-checker.png');
gmReport('gm101-alpha-preview',["gmagick.construct", "gmagick.thumbnailimage", "gmagick.setimagemattecolor", "gmagick.setimagedepth", "gmagick.setimageformat", "gmagick.writeimage", "gmagick.getimagehistogram", "gmagickpixel.getcolorvalue", "gmagick.resizeimage", "gmagick.compositeimage"],["gm101-small-logo.png", "gm101-small-checker.png"],
['guarded_method_unavailable'=>$matteAvailable === false && $matteChannel === null,'saved_transparency'=>$hasTransparency,'size_gm101_small_logo'=>gmInspect('gm101-small-logo.png')['width'] === 160 && gmInspect('gm101-small-logo.png')['height'] === 100,'size_gm101_small_checker'=>gmInspect('gm101-small-checker.png')['width'] === 160 && gmInspect('gm101-small-checker.png')['height'] === 100],
$errors ?? [], ['matte_method_available' => $matteAvailable, 'availability_path' => 'guarded_fallback', 'alternative_executed' => true, 'saved_png_has_transparent_pixels' => $hasTransparency]);
echo "gm101-small-logo.png 160x100\ngm101-small-checker.png 160x100\n";
Ожидаемый результат
gm101-small-logo.png 160x100
gm101-small-checker.png 160x100
Запуск: php example.php с Gmagick. Проверенная среда: PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16. Архив содержит точные собственные входы в .b64; gm-fixture.php восстанавливает их и записывает проверочные metrics.json. Изучаемые операции находятся в программе. Исходный logo.png остаётся прозрачным и неизменным.
Для показа на клетках уменьшается отдельный фон, затем поверх него накладывается маленький логотип. Файл small-logo.png остаётся пригодным для других подложек. В проверяемых точках (5,5) alpha осталась 0, а у полосы в (25,50) — 64. Координаты проверки относятся уже к новой геометрии 160 × 100.
Гистограмма подходит для этого небольшого изображения с немногими цветами. Для больших фотографий её построение обрабатывает весь растр и требует памяти для найденных цветов; проверка одного заранее выбранного пикселя дешевле, но не заменяет полный ответ. Размер и исходный формат входа следует учитывать при выборе способа проверки. О размерах и пропорциях см. thumbnailImage и resizeImage.
Подготовить непрозрачную карточку функцией и обработать ошибки
В сервисе подготовки карточек повторяется одна операция: взять прозрачный оригинал, выбрать фон и получить непрозрачный вариант. Вынесем её в функцию catalogCard. Она возвращает новое изображение, поэтому исходный логотип можно использовать снова для другой темы.


<?php
$logo = new Gmagick(__DIR__ . '/logo.png');
$logo->setImageMatteColor('#e5a74a');
$rgb = $logo->getImageMatteColor()->getColor(true);
$color = sprintf('#%02x%02x%02x', $rgb['r'], $rgb['g'], $rgb['b']);
$card = new Gmagick();
$card->newImage(320, 200, $color, 'png');
$card->compositeImage($logo, Gmagick::COMPOSITE_OVER, 0, 0);Малый фрагмент связывает настройку, чтение цвета и наложение. Полная функция получает объект и строку цвета через параметры, читает ширину и высоту исходника, создаёт новый холст и возвращает его через return. clone используется только для копии настроек: вызов функции не меняет свойство matte color исходного объекта. После возврата обычный writeImage записывает полученную карточку.
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
function catalogCard(Gmagick $source, string $background): Gmagick {
$settings = clone $source;
$settings->setImageMatteColor($background);
$rgb = $settings->getImageMatteColor()->getColor(true);
$css = sprintf('#%02x%02x%02x', $rgb['r'], $rgb['g'], $rgb['b']);
$canvas = new Gmagick();
$canvas->newImage($source->getImageWidth(), $source->getImageHeight(), $css, 'png');
$canvas->compositeImage($source, Gmagick::COMPOSITE_OVER, 0, 0);
return $canvas;
}
$source = new Gmagick(__DIR__ . '/logo.png');
$before = $source->getImageSignature();
$card = catalogCard($source, '#e5a74a');
$card->setImageDepth(8);
$card->setImageFormat('PNG');
$card->writeImage(__DIR__ . '/gm101-catalog-card.png');
$decoded = new Gmagick(__DIR__ . '/gm101-catalog-card.png');
$allOpaque = true;
foreach ($decoded->getImageHistogram() as $pixel) {
if ($pixel->getColorValue(Gmagick::COLOR_OPACITY) > 0.0) $allOpaque = false;
}
$errors = [
'bad_color' => gmTry(fn() => catalogCard($source, 'this-is-not-a-color')),
'empty_getter' => gmTry(fn() => (new Gmagick())->getImageMatteColor()),
'array_color' => gmTry(fn() => $source->setImageMatteColor([]))
];
gmReport('gm101-alpha-catalog-function',["gmagick.construct", "gmagick.setimagemattecolor", "gmagick.getimagemattecolor", "gmagickpixel.getcolor", "gmagick.newimage", "gmagick.getimagewidth", "gmagick.getimageheight", "gmagick.compositeimage", "gmagick.getimagesignature", "gmagick.setimagedepth", "gmagick.setimageformat", "gmagick.writeimage", "gmagick.getimagehistogram", "gmagickpixel.getcolorvalue"],["gm101-catalog-card.png"],
['source_pixels_unchanged'=>$before === $source->getImageSignature(),'output_opaque'=>$allOpaque,'bad_color_caught'=>$errors['bad_color']['class'] === 'GmagickPixelException','empty_caught'=>$errors['empty_getter']['class'] === 'GmagickException','wrong_type_caught'=>$errors['array_color']['class'] === 'GmagickException','size_gm101_catalog_card'=>gmInspect('gm101-catalog-card.png')['width'] === 320 && gmInspect('gm101-catalog-card.png')['height'] === 200],
$errors ?? [], ['actual_output_opaque' => $allOpaque, 'source_pixels_preserved' => $before === $source->getImageSignature()]);
echo "gm101-catalog-card.png 320x200\n";
Ожидаемый результат
gm101-catalog-card.png 320x200
Запуск: php example.php с Gmagick. Проверенная среда: PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16. Архив содержит точные собственные входы в .b64; gm-fixture.php восстанавливает их и записывает проверочные metrics.json. Изучаемые операции находятся в программе. Исходный logo.png остаётся прозрачным и неизменным.
Непонятная строка цвета дала GmagickPixelException, чтение свойства пустого изображения — GmagickException, массив вместо допустимого цвета в этом setter — тоже GmagickException. Не подменяем все отказы одним выдуманным TypeError. Для результата проверена непрозрачность всех цветов гистограммы; пиксели исходника и исходный файл сохранены.
Путь данных в catalogCard: исходный Gmagick и строка цвета → копия настройки → GmagickPixel → массив RGB → строка #RRGGBB → новый холст → OVER → возвращённая карточка. При другом фоне вызывающий код меняет только второй аргумент. Функции и возвращаемые значения разобраны в основах функций, отдельная обработка отказов — в исключениях.
Упражнения. Может ли RGBA PNG быть полностью непрозрачным? Да: все значения alpha могут равняться 255. Закрасит ли setImageMatteColor прозрачные места? В показанной операции нет: нужен отдельный фон и наложение. Можно ли заменить проверку наличия канала проверкой одного прозрачного пикселя? Нет: это разные вопросы. Как сохранить универсальный исходник? Записать карточку в другой файл и оставить logo.png отдельно. Следующий шаг — гамма и цветовые метаданные; проверка реального формата файла — в экспорте и кодировании.
Практические вопросы, использованные как задачи
Detect Alpha Channel with ImageMagick: Автор хочет выбирать PNG для изображений с прозрачностью и JPEG для остальных и спрашивает, как обнаружить прозрачность входа. Наш пример разделяет наличие канала и его фактические значения. Он показывает RGBA с полностью непрозрачными пикселями, прозрачный логотип и рабочую проверку гистограммы при отсутствии getter. Формат выбирается по требованиям к результату; одно расширение имени ничего не доказывает.
Set transparent background using ImageMagick and commandline prompt: Автор назначает background none и пробует flatten, но белые пиксели изображения не становятся прозрачными. Мы показываем ту же важную границу на matte color: установка свойства не заменяет изменение пикселей. На собственной эмблеме сравниваются настройка, реальная alpha и явное наложение. Алгоритм удаления белого фона не выдаётся за следствие этого setter.
GraphicsMagick using nodejs not returning correct image: После обработки изображения через GraphicsMagick автор не получает ожидаемый белый фон в прозрачной области при подготовке JPEG. В нашем маршруте фон сначала создаётся как настоящее изображение, затем выполняется OVER. Исходный прозрачный PNG остаётся отдельным файлом. Видимые светлый, тёмный и янтарный варианты доказывают применение цвета до дальнейшего выбора формата экспорта.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Gmagick::getimagematteПроверить наличие matte-канала с учётом доступности
PECL gmagick >= Unknown · gmagick
Gmagick::getimagematte(): intПроверяет наличие matte-канала у активного изображения. Это структурный признак: канал может существовать и содержать только полностью непрозрачные значения. В проверенной сборке этот метод отсутствует, поэтому примеры используют method_exists и отдельную проверку фактической прозрачности. Успешный вызов отсутствующего getter здесь не заявляется.
Gmagick::getimagematte(): intПараметров нет: используются данные активного изображения объекта.
Возврат по официальной странице: сигнатура содержит int, а текст описывает true при наличии matte-канала и false при его отсутствии. Мы сохраняем это различие документации, не выдумывая фактический тип для отсутствующего метода.
Официальная ошибка — GmagickException. Если сам метод не включён в установленную сборку, прямой вызов в PHP даёт Error раньше библиотечной операции; это отдельная граница доступности.
Требуется PECL Gmagick. PHP.net указывает нижнюю границу версии как Unknown; номер PHP в шапке сайта не уточняет её. Доступность метода проверяется у реально установленного расширения. Здесь среда PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16.
Два рабочих сценария с проверкой доступности и альтернативой: Увидеть прозрачность на клетчатой подложке; Уменьшить логотип, сохранив прозрачность.
Gmagick::getimagemattecolorПрочитать свойство matte color как объект цвета
PECL gmagick >= Unknown · gmagick
Gmagick::getimagemattecolor(): GmagickPixelВозвращает цвет свойства matte color активного изображения как отдельный объект GmagickPixel. Это значение настройки изображения; оно не сообщает, есть ли прозрачные пиксели, и само чтение не меняет изображение. Примеры читают RGB-компоненты, затем явно используют их как цвет нового холста.
Gmagick::getimagemattecolor(): GmagickPixelПараметров нет: используются данные активного изображения объекта.
Возврат: GmagickPixel при успехе. Для чтения RGB можно вызвать getColor(true); это массив цвета, а не строка для автоматической передачи в любой графический метод.
Официальная ошибка — GmagickException. Пустой Gmagick действительно вызвал такое исключение в проверенном окружении.
Требуется PECL Gmagick. PHP.net указывает нижнюю границу версии как Unknown; номер PHP в шапке сайта не уточняет её. Доступность метода проверяется у реально установленного расширения. Здесь среда PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16.
Два самостоятельных применения: Проверить, закрашивает ли matte color прозрачные места; Получить светлую и тёмную карточку с реальным фоном.
Источники и обсуждения
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


