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

Дерево руководства
Глава 436 · После первых изображений, методов и файлов
Gmagick: gamma-метаданные PNG и осветление превью
Отличить метку gamma от изменения RGB, проверить настоящий gAMA, исправить подтверждённую ошибку и выпустить превью по известному рецепту.
Отличить метку гаммы от осветления пикселей
Превью товара кажется слишком тёмным. Перед правкой важно различить две задачи: изменить сами RGB-числа или исправить сведения о том, как эти числа следует понимать. Ниже собственная мишень: четыре серые плашки, плавный градиент и цветные детали. У второй плашки записан RGB 64, 64, 64. Смена метки оставляет 64; намеренное осветление пикселей даёт 94. На реальной фотографии результат нужно оценивать по содержимому, а не по одному контрольному месту.
- Вход: RGB 64, 64, 64; согласованная метка 0.45455.
- setImageGamma(1.0): RGB остаётся 64; меняется указание для интерпретации.
- gammaImage(1.4) + согласованная выходная метка: RGB становится 94; пиксели светлее.



Показаны настоящие PNG программы. Их вид в браузере зависит от обработки цветовых метаданных и окружения. Подписи про RGB относятся к декодированным числам; совпадение или различие отображения на вашем экране само по себе не заменяет эти измерения.
$image = new Gmagick(__DIR__ . "/gamma-target.ppm");
$image->setImageGamma(0.45455);
$declared = $image->getImageGamma();
$image->gammaImage(1.4);
$image->setImageGamma($declared);
$image->setImageFormat("PNG");
$image->writeImage("lighter.png");Здесь $image — переменная с объектом, new создаёт его и читает файл; -> вызывает метод. get означает «прочитать», set — «задать»: getImageGamma() возвращает число, setImageGamma(0.45455) меняет метаданные. Число 1.4 у gammaImage — параметр отдельного преобразования пикселей. На этой сборке оно также умножает метку 0.45455 до 0.63637. В нашем художественном рецепте выход должен сохранить исходную согласованную интерпретацию, поэтому после правки пикселей возвращаем метку. Это осветление по желанию автора, а не универсальное преобразование между цветовыми профилями.
<?php
declare(strict_types=1);
require __DIR__ . '/gm101-gamma-fixture.php';
gmRestore();
$source = new Gmagick(__DIR__ . '/gamma-target.ppm');
$source->setImageGamma(0.45455);
$declaredGamma = $source->getImageGamma();
gmPng($source, 'gm101-gamma-compare-source.png');
$retagged = clone $source;
$returned = $retagged->setImageGamma(1.0);
gmPng($retagged, 'gm101-gamma-compare-metadata.png');
$lighter = clone $source;
$lighter->gammaImage(1.4);
$gammaAfterPixelEdit = $lighter->getImageGamma();
$lighter->setImageGamma($declaredGamma);
gmPng($lighter, 'gm101-gamma-compare-pixels.png');
$checks = [
'setter_returns_same_object' => $returned === $retagged,
'metadata_keeps_decoded_pixels' => gmSamePixels('gm101-gamma-compare-source.png', 'gm101-gamma-compare-metadata.png'),
'pixel_edit_changes_decoded_pixels' => !gmSamePixels('gm101-gamma-compare-source.png', 'gm101-gamma-compare-pixels.png'),
'before_gray64' => gmRgb('gm101-gamma-compare-source.png', 100, 40) === [64, 64, 64],
'after_gray94' => gmRgb('gm101-gamma-compare-pixels.png', 100, 40) === [94, 94, 94],
'metadata_header' => gmPngChunks('gm101-gamma-compare-metadata.png')['gamma_integer'] === 100000,
'pixel_edit_metadata_changed' => abs($gammaAfterPixelEdit - 0.63637) < 0.000001,
'output_header' => gmPngChunks('gm101-gamma-compare-pixels.png')['gamma_integer'] === 45455
];
gmReport(
'gm101-gamma-compare',
["gmagick.getimagegamma", "gmagick.setimagegamma", "gmagick.gammaimage"],
["gm101-gamma-compare-source.png", "gm101-gamma-compare-metadata.png", "gm101-gamma-compare-pixels.png"],
$checks,
$errors ?? [],
['declared_gamma' => $declaredGamma, 'gamma_after_pixel_edit' => $gammaAfterPixelEdit]
);
echo "compare: metadata=RGB-unchanged pixels=64-to-94 output-gAMA=45455\n";
Ожидаемый результат
compare: metadata=RGB-unchanged pixels=64-to-94 output-gAMA=45455
Распакуйте архив и выполните php example.php в окружении с Gmagick. Внутри есть вход в base64, его SHA256, исходник генератора и gm101-gamma-fixture.php. Helper восстанавливает вход, сохраняет PNG с глубиной 8 бит на канал и собирает измерения; gmPngChunks читает реальные chunks, gmSamePixels сравнивает сохранённые пиксели. Это служебная проверка примера, а смысл действия показан коротким фрагментом выше. PNG и квитанции появятся после запуска; metrics.json фиксирует результат.
Упражнение: заменить gammaImage(1.4) на setImageGamma(1.4) и назвать это осветлением. Решение: сравнить RGB после декодирования. Setter не пересчитал плашки, поэтому пиксельная задача не решена. Браузер может иначе показать изменённую метку, но это не доказательство пересчёта RGB.
Опорные разделы: гамма-коррекция пикселей, пропорциональные превью, устройство и проверка экспортного файла.
Синтаксис: объект и метод, переменная и число. Собственная схема делает измерение понятным; она не заменяет проверку портрета, фотографии товара или точности печатного цвета.
Проверить gamma в объекте и gAMA в записанном PNG
Теперь сервису нужна точная квитанция PNG: какое значение находилось в объекте и что действительно попало в файл. Вход PPM хранит RGB без gamma-метаданных. На этой сборке его getter возвращает 0. После setImageGamma(0.45455) PNG содержит блок gAMA с целым числом 45455. Одинаковые плашки показывают, что добавление этой записи не было тоновым фильтром.


Показаны настоящие PNG программы. Их вид в браузере зависит от обработки цветовых метаданных и окружения. Подписи про RGB относятся к декодированным числам; совпадение или различие отображения на вашем экране само по себе не заменяет эти измерения.
$image = new Gmagick(__DIR__ . "/gamma-target.ppm");
$before = $image->getImageGamma();
$image->setImageGamma(0.45455);
$image->setImageFormat("PNG");
$image->writeImage("tagged.png");
$saved = new Gmagick("tagged.png");
printf("before=%.0f after=%.5f\n", $before, $saved->getImageGamma());Короткий фрагмент выводит before=0 after=0.45455. PNG состоит из блоков, называемых chunks. В gAMA четыре байта хранят gamma × 100000 в виде беззнакового целого: 0.45455 → 45455. Это характеристика кодирования, а не процент яркости; 0.45455 приблизительно равно 1 / 2.2. Повторное чтение в нашей сборке вернуло примерно 0.454549998, поэтому float сравниваем с допуском 0.000001, а число в gAMA — точно. getImageGamma сообщает состояние объекта; он не заменяет проверку наличия конкретного блока в записанном формате. На нашем PPM значение 0 означает неуказанную gamma, а не линейную gamma 1.0.
<?php
declare(strict_types=1);
require __DIR__ . '/gm101-gamma-fixture.php';
gmRestore();
$image = new Gmagick(__DIR__ . '/gamma-target.ppm');
$before = $image->getImageGamma();
gmPng($image, 'gm101-gamma-readback-untagged.png');
$image->setImageGamma(0.45455);
$inMemory = $image->getImageGamma();
gmPng($image, 'gm101-gamma-readback-tagged.png');
$reopened = new Gmagick(__DIR__ . '/gm101-gamma-readback-tagged.png');
$afterRead = $reopened->getImageGamma();
$header = gmPngChunks('gm101-gamma-readback-tagged.png');
$receipt = [
'before' => $before, 'in_memory' => $inMemory, 'after_read' => $afterRead,
'gAMA_integer' => $header['gamma_integer'], 'gAMA_value' => $header['gamma_integer'] / 100000
];
file_put_contents(__DIR__ . '/gm101-gamma-readback-receipt.json', json_encode($receipt, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
$checks = [
'initial_gamma_zero' => $before === 0.0,
'untagged_header_absent' => gmPngChunks('gm101-gamma-readback-untagged.png')['gamma_integer'] === null,
'memory_gamma' => abs($inMemory - 0.45455) < 0.000001,
'reopened_gamma' => abs($afterRead - 0.45455) < 0.000001,
'exact_gamma_chunk' => $header['gamma_integer'] === 45455,
'raw_pixels_kept' => gmSamePixels('gm101-gamma-readback-untagged.png', 'gm101-gamma-readback-tagged.png')
];
gmReport(
'gm101-gamma-readback',
["gmagick.getimagegamma", "gmagick.setimagegamma"],
["gm101-gamma-readback-untagged.png", "gm101-gamma-readback-tagged.png"],
$checks,
$errors ?? [],
$receipt
);
echo "readback: PPM-gamma=0 untagged-gAMA=absent tagged-gAMA=45455 pixels=same\n";
Ожидаемый результат
readback: PPM-gamma=0 untagged-gAMA=absent tagged-gAMA=45455 pixels=same
Распакуйте архив и выполните php example.php в окружении с Gmagick. Внутри есть вход в base64, его SHA256, исходник генератора и gm101-gamma-fixture.php. Helper восстанавливает вход, сохраняет PNG с глубиной 8 бит на канал и собирает измерения; gmPngChunks читает реальные chunks, gmSamePixels сравнивает сохранённые пиксели. Это служебная проверка примера, а смысл действия показан коротким фрагментом выше. PNG и квитанции появятся после запуска; metrics.json фиксирует результат.
Упражнение: assert($saved->getImageGamma() === 0.45455). Решение: использовать abs($actual - $expected) < 0.000001 для этого значения. Для проверки самого PNG читать gAMA 45455. Отсутствие блока фиксировать отдельно как null; не заменять его молча единицей.
Опорные разделы: гамма-коррекция пикселей, пропорциональные превью, устройство и проверка экспортного файла.
Исправить известную ошибочную метку без второй тоновой коррекции
У генератора каталожной схемы обнаружена конкретная ошибка: известному набору RGB присвоили gamma 1.0, хотя его рецепт требует 0.45455. Мы сами создали этот дефект и знаем правильную метку из рецепта. Поэтому можно исправить только метаданные, не применяя ещё одну гамма-коррекцию к пикселям. Эти условия существенны: яркость неизвестной фотографии не сообщает её исходную gamma.


Показаны настоящие PNG программы. Их вид в браузере зависит от обработки цветовых метаданных и окружения. Подписи про RGB относятся к декодированным числам; совпадение или различие отображения на вашем экране само по себе не заменяет эти измерения.
$original = new Gmagick(__DIR__ . "/gamma-target.ppm");
$original->setImageGamma(1.0);
$fixed = clone $original;
$fixed->setImageGamma(0.45455);
$fixed->setImageFormat("PNG");
$fixed->writeImage("fixed.png");clone создаёт независимый объект; исходник остаётся с меткой 1.0. Функция repairKnownGamma ниже принимает подтверждённое значение, проверяет его и возвращает исправленную копию. Проверка конечного положительного числа — политика нашей функции, а не заявленный PHP.net диапазон setter. Вызов с 0 отклоняется до обращения к библиотеке. В discovery сама библиотека приняла setImageGamma(0), а PNG записался без gAMA: это не корректный способ сообщить гамму неизвестной картинки. Сравнение сохранённых PNG подтверждает одинаковые RGB и разные gAMA.
<?php
declare(strict_types=1);
require __DIR__ . '/gm101-gamma-fixture.php';
gmRestore();
function repairKnownGamma(Gmagick $image, float $knownGamma): Gmagick {
if (!is_finite($knownGamma) || $knownGamma <= 0.0) {
throw new InvalidArgumentException('A known positive gamma is required');
}
$fixed = clone $image;
$fixed->setImageGamma($knownGamma);
return $fixed;
}
$mistagged = new Gmagick(__DIR__ . '/gamma-target.ppm');
$mistagged->setImageGamma(1.0);
$oldGamma = $mistagged->getImageGamma();
gmPng($mistagged, 'gm101-gamma-known-repair-wrong.png');
// The fixture recipe, not its apparent brightness, supplies this value.
$knownGamma = 0.45455;
$fixed = repairKnownGamma($mistagged, $knownGamma);
$newGamma = $fixed->getImageGamma();
gmPng($fixed, 'gm101-gamma-known-repair-fixed.png');
$errors = [
'unknown_gamma' => gmTry(fn() => repairKnownGamma($mistagged, 0.0))
];
$checks = [
'old_gamma_one' => $oldGamma === 1.0,
'known_gamma_assigned' => abs($newGamma - $knownGamma) < 0.000001,
'original_object_kept' => $mistagged->getImageGamma() === 1.0,
'repair_keeps_pixels' => gmSamePixels('gm101-gamma-known-repair-wrong.png', 'gm101-gamma-known-repair-fixed.png'),
'repaired_header' => gmPngChunks('gm101-gamma-known-repair-fixed.png')['gamma_integer'] === 45455
];
gmReport(
'gm101-gamma-known-repair',
["gmagick.getimagegamma", "gmagick.setimagegamma"],
["gm101-gamma-known-repair-wrong.png", "gm101-gamma-known-repair-fixed.png"],
$checks,
$errors ?? [],
['old_gamma' => $oldGamma, 'known_gamma' => $knownGamma, 'new_gamma' => $newGamma]
);
echo "known-repair: gamma=1-to-0.45455 pixels=same unknown-value=rejected\n";
Ожидаемый результат
known-repair: gamma=1-to-0.45455 pixels=same unknown-value=rejected
Распакуйте архив и выполните php example.php в окружении с Gmagick. Внутри есть вход в base64, его SHA256, исходник генератора и gm101-gamma-fixture.php. Helper восстанавливает вход, сохраняет PNG с глубиной 8 бит на канал и собирает измерения; gmPngChunks читает реальные chunks, gmSamePixels сравнивает сохранённые пиксели. Это служебная проверка примера, а смысл действия показан коротким фрагментом выше. PNG и квитанции появятся после запуска; metrics.json фиксирует результат.
Упражнение: загрузчик получил файл со странной меткой, а рецепта производителя нет. Решение: сохранить оригинал и остановить автоматическое «исправление». Сначала выяснить цветовое пространство и профиль источника. Изменение одного числа не заменяет конвертацию профиля и не восстанавливает утраченную информацию.
Опорные разделы: гамма-коррекция пикселей, пропорциональные превью, устройство и проверка экспортного файла.
Как устроены параметры и возвращаемое значение функции, независимая копия clone и обработка исключений.
Из реальной задачи разработчика
How can I fix PNG's gamma using ImageMagick?. Автор хочет изменить gAMA с 1/4.4 до 1/2.2, сохранив вид, но его преобразование даёт другой результат. Сначала разделяем две постановки: исправить доказанно неверную метку или реально изменить кодирование, сохранив воспринимаемый цвет. Наша функция исправления работает только с известным рецептом собственной схемы и доказывает неизменность RGB; для неизвестного источника она не обещает сохранение внешнего вида. Художественная gammaImage-правка вынесена в отдельный пример.
Принять известный рецепт и отклонить неоднозначный вход
Для автоматического потока полезен узкий договор: генератор отдаёт только собственные схемы с gamma 0.45455. Тогда приёмник может принять ожидаемый вход и остановить другой либо неразмеченный. Две картинки ниже имеют одинаковые RGB, однако вторая нарушает договор метаданных. Политика не пытается угадать правильный вид по пикселям.


Показаны настоящие PNG программы. Их вид в браузере зависит от обработки цветовых метаданных и окружения. Подписи про RGB относятся к декодированным числам; совпадение или различие отображения на вашем экране само по себе не заменяет эти измерения.
$image = new Gmagick(__DIR__ . "/gamma-target.ppm");
$image->setImageGamma(0.45455);
$actual = $image->getImageGamma();
if (abs($actual - 0.45455) > 0.000001) {
throw new DomainException("Unexpected gamma");
}Полная программа выделяет проверку в requireKnownGamma. Она отклоняет неуказанное и неожиданное значение; файлы для сравнения сохраняются как учебные свидетели, а не как допущенные к публикации результаты. Ещё три независимых случая показывают границы API: getter и setter на новом пустом Gmagick дают GmagickException, а массив вместо float — TypeError. Для этих ошибок создаются отдельные объекты, рабочий вход не используется для намеренно неверных вызовов. Программа не повторяет чтение после ошибки на пустом Wand.
<?php
declare(strict_types=1);
require __DIR__ . '/gm101-gamma-fixture.php';
gmRestore();
function requireKnownGamma(Gmagick $image, float $expected): void {
$actual = $image->getImageGamma();
if (!is_finite($actual) || $actual <= 0.0 || abs($actual - $expected) > 0.000001) {
throw new DomainException('Input gamma does not match the declared recipe');
}
}
$approved = new Gmagick(__DIR__ . '/gamma-target.ppm');
$approved->setImageGamma(0.45455);
requireKnownGamma($approved, 0.45455);
gmPng($approved, 'gm101-gamma-input-policy-approved.png');
$different = clone $approved;
$different->setImageGamma(1.0);
gmPng($different, 'gm101-gamma-input-policy-different.png');
$unknown = new Gmagick(__DIR__ . '/gamma-target.ppm');
$errors = [
'unexpected_gamma' => gmTry(fn() => requireKnownGamma($different, 0.45455)),
'missing_gamma' => gmTry(fn() => requireKnownGamma($unknown, 0.45455)),
'empty_get' => gmTry(fn() => (new Gmagick())->getImageGamma()),
'empty_set' => gmTry(fn() => (new Gmagick())->setImageGamma(0.45455)),
'wrong_type' => gmTry(fn() => (new Gmagick(__DIR__ . '/gamma-target.ppm'))->setImageGamma([]))
];
$checks = [
'approved_gamma' => abs($approved->getImageGamma() - 0.45455) < 0.000001,
'both_files_have_same_pixels' => gmSamePixels('gm101-gamma-input-policy-approved.png', 'gm101-gamma-input-policy-different.png'),
'unexpected_value_rejected' => $errors['unexpected_gamma']['ok'] === false,
'unknown_value_rejected' => $errors['missing_gamma']['ok'] === false,
'approved_header' => gmPngChunks('gm101-gamma-input-policy-approved.png')['gamma_integer'] === 45455
];
gmReport(
'gm101-gamma-input-policy',
["gmagick.getimagegamma", "gmagick.setimagegamma"],
["gm101-gamma-input-policy-approved.png", "gm101-gamma-input-policy-different.png"],
$checks,
$errors ?? [],
['approved_gamma' => $approved->getImageGamma(), 'unexpected_gamma' => $different->getImageGamma()]
);
echo "policy: known=accepted unexpected=blocked missing=blocked empty-and-type-errors=caught\n";
Ожидаемый результат
policy: known=accepted unexpected=blocked missing=blocked empty-and-type-errors=caught
Распакуйте архив и выполните php example.php в окружении с Gmagick. Внутри есть вход в base64, его SHA256, исходник генератора и gm101-gamma-fixture.php. Helper восстанавливает вход, сохраняет PNG с глубиной 8 бит на канал и собирает измерения; gmPngChunks читает реальные chunks, gmSamePixels сравнивает сохранённые пиксели. Это служебная проверка примера, а смысл действия показан коротким фрагментом выше. PNG и квитанции появятся после запуска; metrics.json фиксирует результат.
Упражнение: считать успешную проверку gamma доказательством правильного цвета любого PNG. Решение: ограничить договор собственным известным источником. В произвольном PNG могут быть sRGB, iCCP и другие цветовые сведения с большим приоритетом. Они требуют отдельного согласованного маршрута; одна gamma не задаёт полный профиль.
Опорные разделы: гамма-коррекция пикселей, пропорциональные превью, устройство и проверка экспортного файла.
Как устроены параметры и возвращаемое значение функции, независимая копия clone и обработка исключений.
Выпустить два превью и квитанцию выбранного рецепта
Соберём практический результат для карточки каталога: обычное превью и вариант с намеренно поднятыми средними тонами. Оба файла имеют размер 160 × 100 и одну согласованную метку 0.45455. Отличается именно содержимое пикселей: контрольная плашка 64 превращается в 94. JSON-квитанция связывает имя, размер, gamma, gAMA и SHA256 каждого результата.



Показаны настоящие PNG программы. Их вид в браузере зависит от обработки цветовых метаданных и окружения. Подписи про RGB относятся к декодированным числам; совпадение или различие отображения на вашем экране само по себе не заменяет эти измерения.
$image = new Gmagick(__DIR__ . "/gamma-target.ppm");
$image->setImageGamma(0.45455);
$image->gammaImage(1.4);
$image->setImageGamma(0.45455);
$image->thumbnailImage(160, 100, true);
$image->setImageFormat("PNG");
$image->writeImage("preview.png");Полная функция makePreview сначала проверяет договор источника, затем работает с clone. Флаг $liftShadows разрешает художественную правку; без него выполняется только уменьшение. Метку восстанавливают из заранее принятого рецепта, а не определяют по яркости результата. thumbnailImage сохраняет пропорции; gmPng ниже явно записывает PNG с глубиной 8 бит на канал. Декодированные RGB и заголовок проверяются уже в сохранённых файлах. Контроль одной плашки объясняет действие, а сравнение всех пикселей отделяет два результата. Для внешних фотографий нужен цветоуправляемый импорт; этот небольшой пример не притворяется ICC-конвертером.
<?php
declare(strict_types=1);
require __DIR__ . '/gm101-gamma-fixture.php';
gmRestore();
function makePreview(Gmagick $source, bool $liftShadows): Gmagick {
$declared = $source->getImageGamma();
if (abs($declared - 0.45455) > 0.000001) {
throw new DomainException('This recipe requires the known fixture encoding');
}
$preview = clone $source;
if ($liftShadows) {
$preview->gammaImage(1.4);
}
// This artistic edit keeps the output interpretation chosen for our fixture.
$preview->setImageGamma($declared);
$preview->thumbnailImage(160, 100, true);
return $preview;
}
$source = new Gmagick(__DIR__ . '/gamma-target.ppm');
$source->setImageGamma(0.45455);
gmPng($source, 'gm101-gamma-web-preview-source.png');
$standard = makePreview($source, false);
$lighter = makePreview($source, true);
gmPng($standard, 'gm101-gamma-web-preview-standard.png');
gmPng($lighter, 'gm101-gamma-web-preview-lighter.png');
$receipt = [];
foreach (['gm101-gamma-web-preview-standard.png', 'gm101-gamma-web-preview-lighter.png'] as $name) {
$file = new Gmagick(__DIR__ . '/' . $name);
$receipt[] = [
'filename' => $name, 'width' => $file->getImageWidth(), 'height' => $file->getImageHeight(),
'gamma' => $file->getImageGamma(), 'gAMA_integer' => gmPngChunks($name)['gamma_integer'],
'sha256' => hash_file('sha256', __DIR__ . '/' . $name)
];
}
file_put_contents(__DIR__ . '/gm101-gamma-web-preview-receipt.json', json_encode($receipt, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
$checks = [
'source_metadata_kept' => abs($source->getImageGamma() - 0.45455) < 0.000001,
'source_pixels_kept' => gmRgb('gm101-gamma-web-preview-source.png', 100, 40) === [64, 64, 64],
'preview_size' => $standard->getImageWidth() === 160 && $standard->getImageHeight() === 100 && $lighter->getImageWidth() === 160 && $lighter->getImageHeight() === 100,
'preview_pixels_different' => !gmSamePixels('gm101-gamma-web-preview-standard.png', 'gm101-gamma-web-preview-lighter.png'),
'standard_patch' => gmRgb('gm101-gamma-web-preview-standard.png', 50, 20) === [64, 64, 64],
'lighter_patch' => gmRgb('gm101-gamma-web-preview-lighter.png', 50, 20) === [94, 94, 94],
'same_declared_encoding' => $receipt[0]['gAMA_integer'] === 45455 && $receipt[1]['gAMA_integer'] === 45455
];
gmReport(
'gm101-gamma-web-preview',
["gmagick.getimagegamma", "gmagick.setimagegamma", "gmagick.gammaimage"],
["gm101-gamma-web-preview-source.png", "gm101-gamma-web-preview-standard.png", "gm101-gamma-web-preview-lighter.png"],
$checks,
$errors ?? [],
$receipt
);
echo "web-preview: 160x100 standard-gray=64 lighter-gray=94 both-gAMA=45455 receipt=written\n";
Ожидаемый результат
web-preview: 160x100 standard-gray=64 lighter-gray=94 both-gAMA=45455 receipt=written
Распакуйте архив и выполните php example.php в окружении с Gmagick. Внутри есть вход в base64, его SHA256, исходник генератора и gm101-gamma-fixture.php. Helper восстанавливает вход, сохраняет PNG с глубиной 8 бит на канал и собирает измерения; gmPngChunks читает реальные chunks, gmSamePixels сравнивает сохранённые пиксели. Это служебная проверка примера, а смысл действия показан коротким фрагментом выше. PNG и квитанции появятся после запуска; metrics.json фиксирует результат.
Упражнение: оптимизатор уменьшил размер PNG и удалил gAMA, при этом RGB сохранились. Решение: проверить цветовые chunks и ожидаемый вид в целевых клиентах до приёмки. Если источник имеет известный договор, восстановить соответствующие сведения осмысленно; не добавлять gammaImage «на глаз» в ответ на любую смену отображения. SHA256 всего файла и равенство декодированных RGB отвечают на разные вопросы.
Опорные разделы: гамма-коррекция пикселей, пропорциональные превью, устройство и проверка экспортного файла.
Из реальной задачи разработчика
Why do the color profile/spaces of my PNG images change when processed with Perl's Image::Magick?. После чтения, уменьшения и записи PNG через PerlMagick цвета выглядят иначе; автор замечает различие при смене цветового пространства и формата. Проверяем исходный и сохранённый файл раздельно: RGB, gAMA и другие цветовые сведения. В рецепте превью известная метка задаётся явно, а файл перечитывается. Смена PNG на JPEG или слепое удаление метаданных не выдаются за общее исправление, и команды другого расширения не переносятся в Gmagick без проверки.
Из реальной задачи разработчика
Why does tinypng make pics brighter?. После PNG-оптимизации некоторые изображения кажутся светлее; вопрос связывает это с уменьшением палитры и удалением метаданных. Различаем изменение RGB при квантовании и изменение интерпретации при удалении цветовых chunks. Квитанция фиксирует gAMA, а сравнение декодированных пикселей отвечает на другой вопрос. Для внешнего оптимизатора проверяют реальный выход и целевое отображение; сам сервис здесь не вызывается и его нынешнее поведение не предполагается.
Граница web-сценария: PNG gAMA описывает степенную характеристику, но не весь профиль. По спецификации декодер учитывает приоритет цветовых chunks; sRGB и iCCP могут определять интерпретацию вместо gAMA. Нельзя обещать одинаковое отображение во всех браузерах только по одному getter. Эта глава проверяет метаданные и пиксели файла, а не калибрует монитор и не выполняет ICC-преобразование.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Gmagick::getimagegammaПрочитать gamma текущего изображения и проверить экспорт
PECL gmagick >= Unknown · gmagick
Gmagick::getimagegamma(): floatМетод читает gamma текущего изображения. Аргументов нет; результат float — значение gamma при успехе. Чтение само по себе не осветляет изображение, не вычисляет экспозицию по его RGB и не устанавливает цветовой профиль. В этой главе getter проверяет сохранённый PNG и служит условием приёмки известного источника. На нашем PPM без метки возвращается 0; это наблюдение входа и сборки, а не доказательство наличия gAMA или универсальная диагностика всех форматов. После PNG с gAMA 45455 getter возвращает примерно 0.454549998. Для этого значения сравнивайте float с небольшим допуском, а наличие блока подтверждайте по файлу.
Gmagick::getimagegamma(): floatПараметров нет. Пустые скобки () означают вызов без аргументов, а не передачу нуля.
Официальная ошибка — GmagickException. Для обоих методов она воспроизведена на пустом объекте без изображения. У setter массив вместо float даёт TypeError; отсутствие обязательного аргумента в discovery дало ArgumentCountError. DomainException и InvalidArgumentException в наших функциях — отдельные прикладные проверки, не обещанные ошибки Gmagick.
Два разных применения и развитие задачи: Проверить gamma в объекте и gAMA в записанном PNG; Принять известный рецепт и отклонить неоднозначный вход; Выпустить два превью и квитанцию выбранного рецепта.
Связанный метод gammaImage — изменение пикселей решает другую задачу. На проверенной сборке он также обновил gamma-метаданные; при художественной правке согласованный выходной рецепт задаётся явно. Удаление всех метаданных также не является универсальной коррекцией цвета: см. границы stripImage.
PHP.net указывает PECL gmagick ≥ Unknown: точная минимальная версия там не задана. Наблюдения главы относятся к PHP 8.3.6, Gmagick 2.0.6RC1 и GraphicsMagick 1.3.42 Q16. Поддержка сохранения gamma зависит от формата; здесь реально проверяется PNG, не обещается аналогичный блок в JPEG.
Gmagick::setimagegammaЗадать gamma-метаданные, сохранив RGB-пиксели
PECL gmagick >= Unknown · gmagick
Gmagick::setimagegamma(float $gamma): GmagickМетод задаёт gamma текущего изображения. Единственный обязательный параметр $gamma имеет тип float; значения по умолчанию нет. Возвращается Gmagick, в проверенной реализации тот же объект, поэтому цепочка вызовов возможна. Setter меняет характеристику изображения, но не выполняет тоновую коррекцию RGB. Для нашей схемы 0.45455 записывается в PNG как gAMA 45455; 1.0 — как 100000. Это не процент яркости и не гамма-коррекция с силой 45 %. PHP.net не определяет диапазон допустимых значений. Прикладная функция принимает только известное конечное положительное число. Принятый библиотекой 0 на нашем PNG привёл к отсутствию gAMA, поэтому не используйте его как «нейтральное» значение вместо 1.0. Запись файла выполняется отдельно через writeImage.
Gmagick::setimagegamma(float $gamma): Gmagick| Параметр | Контракт | Смысл |
|---|---|---|
| $gamma | float; обязательный; без default | Gamma-метаданные текущего изображения. Положительное известное значение проверяется нашим приложением; setter не выбирает его по пикселям. |
Официальная ошибка — GmagickException. Для обоих методов она воспроизведена на пустом объекте без изображения. У setter массив вместо float даёт TypeError; отсутствие обязательного аргумента в discovery дало ArgumentCountError. DomainException и InvalidArgumentException в наших функциях — отдельные прикладные проверки, не обещанные ошибки Gmagick.
Два разных применения и развитие задачи: Отличить метку гаммы от осветления пикселей; Исправить известную ошибочную метку без второй тоновой коррекции; Выпустить два превью и квитанцию выбранного рецепта.
Связанный метод gammaImage — изменение пикселей решает другую задачу. На проверенной сборке он также обновил gamma-метаданные; при художественной правке согласованный выходной рецепт задаётся явно. Удаление всех метаданных также не является универсальной коррекцией цвета: см. границы stripImage.
PHP.net указывает PECL gmagick ≥ Unknown: точная минимальная версия там не задана. Наблюдения главы относятся к PHP 8.3.6, Gmagick 2.0.6RC1 и GraphicsMagick 1.3.42 Q16. Поддержка сохранения gamma зависит от формата; здесь реально проверяется PNG, не обещается аналогичный блок в JPEG.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


