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

Дерево руководства
Глава 346 · После загрузки изображения
Imagick: тусклый диапазон, выбросы и управляемое растяжение
От первого автоматического PNG до гистограммы, разных единиц двух stretchAPI, защищённых шкал, выбранного канала и двух размеров превью.
От тусклого макета к первому PNG
Каталожная иллюстрация после неудачного экспорта стала сероватой и тусклой. Нужно подготовить более различимый вариант, сохранив оригинал и понимая, какие детали могут исчезнуть. Начнём с одного PNG: рядом будут исходник и автоматические уровни. Затем сравним устойчивость к редким выбросам, управляемые хвосты, отдельный канал и превью другого размера.


Главная запись $image->autoLevelImage(); найдёт крайние значения и расширит диапазон. $image — переменная с объектом изображения; стрелка вызывает его метод. Скобки пустые, потому что channel необязателен; точка с запятой завершает команду. На нашем входе min/max равны 20/230, а большинство компонентов находится в 70..190: автоматике неизвестно, что две крайние метки служебные.
$image = clone $source;
$image->autoLevelImage();В полной программе $source будет загружен из приложенного файла. Clone создаёт независимую копию; $image = $source оставило бы два имени одного объекта. Исходник специальный: взят наш собственный рисунок каталога, его RGB-компоненты сжаты в 70..190, добавлены серые плашки 70/100/130/160/190 и по 36 пикселей 20/230 в верхних углах. Это учебный рисунок, не измерение реального товара.
SaveStretchComparison([$source, $image], 'stretch-first.png') получает массив двух изображений: квадратные скобки создают список, первая панель слева. Помощник соберёт PNG8 и выведет имя файла. If с ! проверяет false, throw прекращает обработку понятным отказом; clear после записи освобождает ресурсы. Помощник целиком показан в разделе о единицах.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
if (!$image->autoLevelImage()) {
throw new RuntimeException('Не удалось применить autoLevelImage');
}
saveStretchComparison([$source, $image], 'stretch-first.png');
$source->clear();
$image->clear();
Результат: Справа автоматические уровни по фактическому минимуму и максимуму. Две маленькие плашки 20 и 230 стали краями 0 и 255; серые 70/100/130/160/190 в сохранённом PNG8 стали 60/97/133/170/206. Картинка контрастнее, но выбросы всё ещё ограничивают полезное растяжение: основные уровни заняли только внутреннюю часть диапазона. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
stretch-first.png
Крайние значения и хвосты гистограммы

Напечатанные над плашками числа 70/100/130/160/190 обозначают исходные значения. Фильтр меняет пиксели рисунка, но не понимает текст надписей и не пересчитывает его. Фактические значения после обработки приведены в сравнительной схеме и пояснениях к программам.
Гистограмма — счётчик количества пикселей на каждом уровне. Min/max смотрят на крайние занятые значения. Хвостовая отсечка накапливает количество от края и выбирает границу по заданному счётчику; затем значения между двумя границами распределяются шире. Пиксели за границами насыщаются до крайних значений. Это не распознавание шума: полезный блик и дефект одного уровня получат одинаковую обработку.
| Цель | Операция | Главное различие |
|---|---|---|
| Быстрый min/max | autoLevelImage | Даже одна крайняя точка участвует в границе. |
| Готовая политика выбросов | normalizeImage | В этой версии нижние 2% и верхний 1%; параметры долей не задаются. |
| Свои границы популяции | contrastStretchImage | Чёрная позиция снизу и белая позиция тоже снизу. |
| Два счётчика хвостов | linearStretchImage | Чёрный хвост снизу, белый хвост сверху; channel-аргумента нет. |
Перед полной сравнительной программой разберём её ядро. У autoLevel и normalize пустые скобки выбирают default channel. В двух stretch-вызовах $pixels — число пикселей текущего растра, не QuantumRange. Числа 0.01/0.99 становятся долями только после умножения на $pixels; у contrast и linear второй аргумент имеет разный смысл. Для каждого вызова далее создаётся своя clone-копия исходника.
$image->autoLevelImage();
$normalized->normalizeImage();
$contrasted->contrastStretchImage($pixels * 0.01, $pixels * 0.99);
$linear->linearStretchImage($pixels * 0.01, $pixels * 0.01);Это поясняющий фрагмент: переменные с изображениями и $pixels будут созданы в полной программе. Стрелка вызывает метод соответствующего объекта, запятая отделяет аргументы, звёздочка умножает, точка с запятой завершает действие. На рисунке порядок панелей совпадает с порядком списка в помощнике.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
if (!$image->autoLevelImage()) {
throw new RuntimeException('Не удалось применить autoLevelImage');
}
$normalized = clone $source;
if (!$normalized->normalizeImage()) {
throw new RuntimeException('Не удалось применить normalizeImage');
}
$contrasted = clone $source;
$pixels = $source->getImageWidth() * $source->getImageHeight();
if (!$contrasted->contrastStretchImage($pixels * 0.01, $pixels * 0.99)) {
throw new RuntimeException('Не удалось применить contrastStretchImage');
}
$linear = clone $source;
if (!$linear->linearStretchImage($pixels * 0.01, $pixels * 0.01)) {
throw new RuntimeException('Не удалось применить linearStretchImage');
}
saveStretchComparison([$source, $image, $normalized, $contrasted, $linear], 'stretch-controls.png');
$source->clear();
$image->clear();
$normalized->clear();
$contrasted->clear();
$linear->clear();
Результат: Панели: исходник, autoLevelImage(), normalizeImage(), contrastStretchImage(1280,126720), linearStretchImage(1280,1280). Все копии получены из одного входа. Редкие 20/230 участвуют в min/max; выбранные популяции позволяют другим операциям ориентироваться на основное содержимое. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 2000×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
stretch-controls.png
Не перепутать уровни, quantum и число пикселей
Есть три разные шкалы. Сохранённый PNG8 использует уровни 0..255 на канал. Native-библиотека Q16 работает до QuantumRange=65535. А параметры contrastStretch/linearStretch в этой PHP-обвязке — количества пикселей: у 400×320 N=128000. Например, 1% от N=1280; это не уровень 1280 и не quantum-порог. Для contrast второй аргумент 99%×N=126720, для linear верхний хвост 1%×N=1280.
| Требование при N=128000 | contrastStretchImage | linearStretchImage |
|---|---|---|
| 1% снизу, 1% сверху | (1280,126720) | (1280,1280) |
| 2% снизу, 1% сверху | (2560,126720) | (2560,1280) |
| Уменьшенное 200×160, 1%/1% | (320,31680) | (320,320) |
При 100 пикселях ровно один крайний выброс и счётчик 1 дают пограничный случай. В ImageMagick 7.1.1-46 contrast накапливает до строгого >, linear — до >=. Поэтому contrast(1,99) и linear(1,1) могут выбрать разные уровни даже на одной серой шкале. Нельзя обещать попиксельное равенство двух методов лишь по совпавшим процентам.
Полный переносимый помощник входа и записи панелей
<?php
declare(strict_types=1);
function loadStretchSource(): Imagick
{
$encoded = file_get_contents(__DIR__ . '/source.png.b64');
if ($encoded === false) {
throw new RuntimeException('Не найден source.png.b64: распакуйте весь архив');
}
$bytes = base64_decode($encoded, true);
if ($bytes === false || hash('sha256', $bytes) !== '46f39b4aa79064915aae554dce86175c6edd2f0cecce7cc965c67e46b2b5dd47') {
throw new RuntimeException('Повреждён исходный PNG');
}
$path = __DIR__ . '/source.png';
if (file_put_contents($path, $bytes) !== strlen($bytes)) {
throw new RuntimeException('Не удалось восстановить source.png');
}
return new Imagick($path);
}
function saveStretchComparison(array $panels, string $filename): void
{
if ($panels === []) {
throw new InvalidArgumentException('Нужна хотя бы одна панель');
}
$output = new Imagick();
$output->newImage(400 * count($panels), 320, 'white');
$output->setImageFormat('png');
foreach ($panels as $index => $panel) {
if (!$panel instanceof Imagick || $panel->getImageWidth() !== 400 || $panel->getImageHeight() !== 320) {
throw new InvalidArgumentException('Панель должна быть Imagick 400 на 320 пикселей');
}
if (!$output->compositeImage($panel, Imagick::COMPOSITE_OVER, 400 * $index, 0)) {
throw new RuntimeException('Не удалось собрать сравнение');
}
}
$output->setImageDepth(8);
$output->setOption('png:color-type', '2');
if (!$output->writeImage(__DIR__ . '/' . $filename)) {
throw new RuntimeException('Не удалось записать результат');
}
$output->clear();
echo $filename, "\n";
}
Помощник читает Base64 через file_get_contents, проверяет base64_decode и hash и пишет исходный PNG через file_put_contents. CompositeImage переносит панели на полотно; setImageDepth(8) и png:color-type=2 сохраняют RGB PNG8. Это обвязка учебного опыта, не дополнительная операция растяжения. Папка должна быть доступна для записи. Нарисованный текст уже находится в пикселях; файл шрифта в архиве не нужен.
Квантование ограничивает число записываемых уровней. Конкретные RGB-значения рисунков относятся к сохранённым PNG8, а не к округлённому экспорту Q16-пикселя. RGB — три составляющие цвета; sRGB — цветовое представление нашего входа. Linear RGB, ICC/CMYK и HDR требуют отдельных решений. Подготовка: массив и ключ, объект, clone, файлы, исключения.
Отделить выбросы от полезной детали


Отсечь хвост — значит разрешить потерю части различий. Маленький блик на кружке, тонкий тёмный штрих и шум могут лежать в одном хвосте. Увеличение доли не означает обязательное улучшение: изучайте форму предмета, буквы, светлые переходы и тени. Одинаковый уровень может встречаться тысячами пикселей, поэтому доля выбрана по накопленной гистограмме, а не по обещанию изменить ровно N×процент пикселей.
Выбор области и отсечение популяции решают разные задачи. Известный прямоугольник исключает служебные поля целиком и позволяет оставить их точными. Процентный хвост работает по всему выбранному содержимому и не знает, какие пиксели служебные. Нормализация каждого кадра отдельно также не гарантирует одинаковый цвет или освещение между двумя фотографиями; для серии нужна согласованная политика и контрольные образцы.
Не спутать область, цветовой канал и alpha

Канал — составляющая пикселя, а не предмет определённого цвета. Маска RED изменяет R у всего выбранного растра; G/B остаются прежними. Синхронизированные общие границы и независимые канальные границы могут давать разные цвета. При default текущая библиотека использует свою маску; не объявляйте результат способом правильного баланса белого или сохранения воспринимаемой яркости.
Alpha описывает непрозрачность. В нашей ограниченной проверке default менял её; явная Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE у autoLevel/normalize/contrastStretch сохранила alpha. Не подставляйте CHANNEL_ALL как синоним RGB. Для linearStretch отдельного channel нет; перед прозрачным рабочим файлом потребуется отдельное сохранение/возврат alpha либо другая согласованная цепочка с проверкой.
Изменённый R в проверке одного канала полезен как диагностический вариант. Для нейтрального документа выберите серое преобразование отдельно; для цветного каталога оценивайте реальные цвета. Тонирование и цветовые эффекты имеют другую цель и не заменяют исправление диапазона.
Оценить результат и обработать отказ
Перед обработкой определите, что считать успехом: различимые детали, сохранённые шкалы, выбранная доля отсечки или одинаковая политика для двух размеров. Проверяйте не только минимум/максимум, но и полезную середину, надпись, блики и тень. Автоматическая растяжка не исправляет локальную тень, не восстанавливает уже потерянные данные и не гарантирует лучшую картинку для каждого товара.
Чтение, native-операция и запись — отдельные точки отказа. Проверяйте формат, площадь, число кадров, профили и право записи; ограничьте число clone-копий и разрешение. Гистограмма и проход по пикселям требуют памяти и времени; точную стоимость измеряйте на своей цепочке. Суммарная площадь важнее одного размера файла. Не вызывайте тяжёлый фильтр без ограничений для произвольной загрузки.
Проверенный runtime: PHP 8.5.11, Imagick 3.8.1, ImageMagick 7.1.1-46 Q16. Одна ограниченная предварительная проверка установила единицы и пограничные случаи; десять новых программ создали настоящие PNG8. Не переносите численные особенности другой сборки или названия ползунков редактора без проверки. На ровной плашке autoLevel/normalize/contrast сохранили тон, linear сделал чёрный. Практическая политика: сначала сравните минимальное и максимальное значения рабочего диапазона. Если minimum == maximum, сохраните исходник и пропустите растяжение: делить и расширять отсутствующий диапазон не требуется. Возвращаемое true такую проверку не заменяет.
Выбрать политику и сделать самостоятельный вариант

- Нет мешающих крайних точек: начните с autoLevel и сравнения с исходником.
- Редкие крайние значения мешают: сравните normalize с его фиксированной политикой этой версии.
- Нужна своя отсечка: вычислите N и задайте contrast-позиции или linear-хвосты, явно различая второй аргумент.
- Нужно сохранить поля: ограничьте известную область, пересчитайте N после crop.
- Нужны разные разрешения: пересчитайте N после resize, проверьте результат каждого размера.
Упражнение: улучшить только картинку товара и точно сохранить обе нижние шкалы. Решение: clone исходника; crop352×184 в(24,36); посчитать 64768 пикселей; применить contrastStretchImage(0.01×N,0.99×N); вернуть область в исходную копию через compositeImage. Проверка: пиксели снаружи совпадают, внутри диапазон изменился. Полная программа: защищённые шкалы. Затем уменьшите рабочую копию вдвое и объясните, почему два счётчика хвостов тоже уменьшаются вчетверо.
Дальше: явные уровни и gamma, порог и полутоновая отсечка, цветовой вариант, сохранение производных файлов. Новую настройку применяйте к оригиналу: насыщение до чёрного/белого уничтожает различия, которые обратная растяжка не восстановит.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::autoLevelImageКартинка выглядит тусклой, поскольку её значения используют только часть доступного диапазона. Нужна быстрая исходная попытка без выбора двух отсечек.
PECL imagick 3 >= 3.3.0 · imagick
Imagick::autoLevelImage(int $channel = Imagick::CHANNEL_DEFAULT): boolКартинка выглядит тусклой, поскольку её значения используют только часть доступного диапазона. Нужна быстрая исходная попытка без выбора двух отсечек.

Самая маленькая запись
В $image уже находится независимая копия рисунка. Пустые скобки допустимы: единственный аргумент channel необязателен и берётся CHANNEL_DEFAULT. В нашей копии метод растянет крайние 20/230 к 0/255; главная картинка с диапазоном 70..190 займёт внутреннюю часть. Стрелка вызывает метод объекта; круглые скобки содержат аргументы, точка с запятой завершает команду. До изменения создайте $image = clone $source: присваивание без clone оставило бы два имени одного объекта.
$image->autoLevelImage();Это поясняющий фрагмент. Полная программа ниже загрузит переносимый вход, проверит возврат и сохранит PNG. Основы: объект и метод, копирование, аргумент вызова.
Сигнатура и параметры
Imagick::autoLevelImage(int $channel = Imagick::CHANNEL_DEFAULT): boolМетод ищет текущий минимум и максимум и растягивает их к полному QuantumRange. В простой модели result=(value−minimum)/(maximum−minimum)×QuantumRange. В нашей RGB-копии крайние нейтральные точки 20/230 задают общий диапазон. Метод не отличает полезную деталь от выброса.
| Аргумент | Смысл, единицы и default |
|---|---|
| $channel | Необязательный int, default Imagick::CHANNEL_DEFAULT; без аргумента запись autoLevelImage() допустима. Канал или комбинация констант задаёт, какие составляющие обрабатывать. Режим синхронизации также влияет на общие либо независимые границы. |
Возвращаемое значение, версии и отказ
Возвращается bool: true при успехе. Метод меняет пиксели текущего объекта Imagick; $ok = $image->autoLevelImage(...) сохранит флаг, не новую картинку. Доступность по PHP Manual: PECL imagick 3 >= 3.3.0. Обязательные параметры и default сохранены в сигнатуре выше.
AutoLevelImage добавлен в PECL imagick 3.3.0; точная C-сборка также содержит условие MagickLibVersion >0x655, то есть библиотека новее 6.5.5. Проверьте наличие метода при поддержке старых установок.
Хотя у этих страниц нет отдельного описания ошибок, точная обвязка и preflight подтверждают ImagickException на пустом изображении и преобразование native-отказа в исключение. Чтение и запись могут отказать отдельно. В полном коде ! означает «вернулся false», throw создаёт отказ; clear освобождает native-ресурсы. Для сайта перехватите исключение и выдайте понятное сообщение без внутренних путей. True не обещает нужного качества, допустимых настроек или сохранения деталей.
Первый управляемый результат
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
if (!$image->autoLevelImage()) {
throw new RuntimeException('Не удалось применить autoLevelImage');
}
saveStretchComparison([$source, $image], 'auto-level-basic.png');
$source->clear();
$image->clear();
Результат: Справа автоматические уровни по фактическому минимуму и максимуму. Две маленькие плашки 20 и 230 стали краями 0 и 255; серые 70/100/130/160/190 в сохранённом PNG8 стали 60/97/133/170/206. Картинка контрастнее, но выбросы всё ещё ограничивают полезное растяжение: основные уровни заняли только внутреннюю часть диапазона. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
auto-level-basic.png
Практическая задача: Исключить посторонние крайние точки выбором области товара
Края макета содержат служебные метки, но контраст нужен самой картинке коробки и кружки. Знаем её прямоугольник и вычисляем min/max только внутри него; нижние шкалы и внешние выбросы оставляем без изменения.
CropImage получает ширину 352,высоту 184 и начало x=24,y=36; setImagePage сбрасывает виртуальное смещение вырезки. CompositeImage с COMPOSITE_OVER возвращает готовую область в(24,36). Переменная $region хранит отдельный объект; координаты задаёт макет, библиотека не узнаёт предмет сама. Границы и гистограмма определяются внутри вырезки.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
$region = clone $source;
$region->cropImage(352, 184, 24, 36);
$region->setImagePage(0, 0, 0, 0);
if (!$region->autoLevelImage()) {
throw new RuntimeException('Не удалось применить autoLevelImage');
}
if (!$image->compositeImage($region, Imagick::COMPOSITE_OVER, 24, 36)) {
throw new RuntimeException('Не удалось вернуть область');
}
$region->clear();
saveStretchComparison([$source, $image], 'auto-level-region.png');
$source->clear();
$image->clear();
Результат: Справа обработан только прямоугольник x=24..375,y=36..219. Все внешние пиксели совпадают с исходником. Внутри найден собственный диапазон и растянут на полный; крайние метки 20/230 за пределами области на это вычисление не влияют. Это осознанное ограничение известного макета, не автоматическое обнаружение предмета. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
auto-level-region.png
Ошибки, ограничения и альтернативы
Даже единичный крайний пиксель способен ограничить min/max. Если уже есть 0 и QuantumRange, полезного расширения может не быть. На ровной плашке 50% в нашей проверке метод вернул true и оставил значение прежним: отсутствующий контраст не возникает из ничего. Для контролируемой устойчивости к выбросам нужны другие критерии или выбранная область.
Основные программы используют один непрозрачный sRGB PNG. На отдельном RGBA-образце нашей сборки default этих четырёх операций менял alpha; у трёх методов с channel явная маска RED|GREEN|BLUE сохранила её. У linearStretchImage channel-аргумента нет. Для прозрачных файлов заранее выберите и проверьте самостоятельную политику alpha. Цветовые профили и многокадровые файлы также требуют отдельной обработки.
Соседние методы: normalizeImage · contrastStretchImage · linearStretchImage. Для яркости, контраста и gamma: гамма, яркость и контраст; для двоичного документа: пороги.
Imagick::normalizeImageРедкие крайние метки или отдельные дефекты не должны сжимать полезный диапазон всей картинки. Нужна готовая автоматическая политика.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::normalizeImage(int $channel = Imagick::CHANNEL_DEFAULT): boolРедкие крайние метки или отдельные дефекты не должны сжимать полезный диапазон всей картинки. Нужна готовая автоматическая политика.

Самая маленькая запись
В $image находится независимая копия. Пустые скобки выбирают default channel. Нормализация найдёт границы своей встроенной политики; на нашем входе редкие 20/230 не будут единственными опорами диапазона. Это решение по гистограмме, не распознавание коробки или дефекта. Стрелка вызывает метод объекта; круглые скобки содержат аргументы, точка с запятой завершает команду. До изменения создайте $image = clone $source: присваивание без clone оставило бы два имени одного объекта.
$image->normalizeImage();Это поясняющий фрагмент. Полная программа ниже загрузит переносимый вход, проверит возврат и сохранит PNG. Основы: объект и метод, копирование, аргумент вызова.
Сигнатура и параметры
Imagick::normalizeImage(int $channel = Imagick::CHANNEL_DEFAULT): boolОбщее описание PHP Manual обещает расширение доступного диапазона. Точная ImageMagick 7.1.1-46 реализует NormalizeImage через ContrastStretchImage с black_point=0.02×N и white_point=0.99×N: нижние 2% и верхний 1% по накопленной гистограмме. Это конкретная встроенная политика, а не просто другое имя autoLevel.
| Аргумент | Смысл, единицы и default |
|---|---|
| $channel | Необязательный int, default Imagick::CHANNEL_DEFAULT. Для нескольких каналов константы объединяются побитовым |. Явный CHANNEL_RED в нашей программе меняет R и оставляет G/B. В старой совместимой ветви wrapper до поддержки channel маска игнорируется; точная текущая сборка проверена отдельно. |
Возвращаемое значение, версии и отказ
Возвращается bool: true при успехе. Метод меняет пиксели текущего объекта Imagick; $ok = $image->normalizeImage(...) сохранит флаг, не новую картинку. Доступность по PHP Manual: PECL imagick 2, PECL imagick 3. Обязательные параметры и default сохранены в сигнатуре выше.
В старой ветви PHP-обвязки channel передаётся в специальный native-вызов только при MagickLibVersion >0x628; иначе используется вызов без канала. Не переносите маску текущей версии на старую библиотеку по одной PHP-сигнатуре.
Хотя у этих страниц нет отдельного описания ошибок, точная обвязка и preflight подтверждают ImagickException на пустом изображении и преобразование native-отказа в исключение. Чтение и запись могут отказать отдельно. В полном коде ! означает «вернулся false», throw создаёт отказ; clear освобождает native-ресурсы. Для сайта перехватите исключение и выдайте понятное сообщение без внутренних путей. True не обещает нужного качества, допустимых настроек или сохранения деталей.
Первый управляемый результат
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
if (!$image->normalizeImage()) {
throw new RuntimeException('Не удалось применить normalizeImage');
}
saveStretchComparison([$source, $image], 'normalize-basic.png');
$source->clear();
$image->clear();
Результат: Справа нормализация этой сборки с нижней отсечкой 2% и верхней 1% по гистограмме. Редкие значения 20 и 230 перестали определять растяжение. Серые 70/100/130/160/190 в сохранённом PNG8 стали 0/48/117/186/255; это шире, чем после autoLevel. Пиксели у выбранных границ могут слиться в чёрный или белый. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
normalize-basic.png
Практическая задача: Проверить нормализацию только красной составляющей
При подборе цветовой коррекции требуется увидеть вклад одной составляющей, сохранив остальные для сравнения. Изменяем только R и сохраняем G/B исходными. Получится служебный вариант для оценки, а не автоматический баланс белого.
Imagick::CHANNEL_RED — именованная константа выбора канала. Двойное двоеточие обращается к константе класса, а не вызывает метод. Если нужны несколько каналов, их объединяют |, например RED | GREEN; это побитовый оператор, отличный от логического ||. В данном опыте цель — изменённый R при точно сохранённых G/B, поэтому выбирается только RED.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
if (!$image->normalizeImage(Imagick::CHANNEL_RED)) {
throw new RuntimeException('Не удалось применить normalizeImage');
}
saveStretchComparison([$source, $image], 'normalize-red-channel.png');
$source->clear();
$image->clear();
Результат: Справа красный канал изменён по его выбранным уровням, зелёный и синий у всех пикселей сохранены точно. Нейтральная шкала может стать цветной: одинаковые исходные R/G/B теперь обработаны неодинаково. Канал выбирает составляющую всего растра, а не красные предметы. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
normalize-red-channel.png
Ошибки, ограничения и альтернативы
Доля отсечки не равна гарантированному числу потерянных пикселей: граница выбирается по уровням и повторяющимся значениям. Полезные тёмные/светлые детали могут попасть в обрезанный хвост. Повторная нормализация не восстанавливает их. На равномерном входе в нашем preflight true не означало появления деталей. Для иной доли используйте явные параметры contrastStretch/linearStretch.
Основные программы используют один непрозрачный sRGB PNG. На отдельном RGBA-образце нашей сборки default этих четырёх операций менял alpha; у трёх методов с channel явная маска RED|GREEN|BLUE сохранила её. У linearStretchImage channel-аргумента нет. Для прозрачных файлов заранее выберите и проверьте самостоятельную политику alpha. Цветовые профили и многокадровые файлы также требуют отдельной обработки.
Соседние методы: autoLevelImage · contrastStretchImage · linearStretchImage. Для яркости, контраста и gamma: гамма, яркость и контраст; для двоичного документа: пороги.
Imagick::contrastStretchImageНужна явная политика: сколько редких тёмных и светлых значений позволить обрезать, сохраняя управляемую середину.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::contrastStretchImage(float $black_point, float $white_point, int $channel = Imagick::CHANNEL_DEFAULT): boolНужна явная политика: сколько редких тёмных и светлых значений позволить обрезать, сохраняя управляемую середину.

Самая маленькая запись
Первая строка получает ширину и высоту текущего изображения; звёздочка умножает их, знак = сохраняет число пикселей в $pixels. У 400×320 получится 128000. Во второй строке запятая отделяет нижний счётчик 1280 от верхней позиции 126720; это 1% снизу и 99% снизу, значит 1% сверху. Стрелка вызывает метод объекта; круглые скобки содержат аргументы, точка с запятой завершает команду. До изменения создайте $image = clone $source: присваивание без clone оставило бы два имени одного объекта.
$pixels = $image->getImageWidth() * $image->getImageHeight();
$image->contrastStretchImage($pixels * 0.01, $pixels * 0.99);Это поясняющий фрагмент. Полная программа ниже загрузит переносимый вход, проверит возврат и сохранит PNG. Основы: объект и метод, копирование, аргумент вызова.
Сигнатура и параметры
Imagick::contrastStretchImage(float $black_point, float $white_point, int $channel = Imagick::CHANNEL_DEFAULT): boolМетод выбирает уровни по накопленной гистограмме и растягивает между ними. В этой PHP-обвязке float передаются напрямую native-библиотеке. Они означают популяционные счётчики, не quantum-яркости и не проценты сами по себе. Для нижнего хвоста a и верхнего b при N пикселях запись contrastStretchImage(a×N,(1−b)×N).
| Аргумент | Смысл, единицы и default |
|---|---|
| $black_point | Обязательный float: нижний накопленный счётчик. Для 1% вычисляем 0.01×N; для 400×320 это 1280. |
| $white_point | Обязательный float: верхняя позиция, отсчитываемая снизу. Для отсечки верхнего 1% используем 0.99×N=126720. Это НЕ 1280, как у второго аргумента linearStretchImage. |
| $channel | Необязательный int, default Imagick::CHANNEL_DEFAULT. Допустима одна константа канала или объединение через |; официальный текст также приводит CHANNEL_ALL. All включает более широкий набор, поэтому его нельзя автоматически считать маской только RGB. |
Возвращаемое значение, версии и отказ
Возвращается bool: true при успехе. Метод меняет пиксели текущего объекта Imagick; $ok = $image->contrastStretchImage(...) сохранит флаг, не новую картинку. Доступность по PHP Manual: PECL imagick 2, PECL imagick 3. Обязательные параметры и default сохранены в сигнатуре выше.
Официальное ограничение: метод доступен при сборке Imagick с ImageMagick 6.2.9 или новее. Это версия библиотеки ImageMagick, отличная от номера расширения Imagick. Исходный XML содержит это ограничение через общую сущность мануала.
Хотя у этих страниц нет отдельного описания ошибок, точная обвязка и preflight подтверждают ImagickException на пустом изображении и преобразование native-отказа в исключение. Чтение и запись могут отказать отдельно. В полном коде ! означает «вернулся false», throw создаёт отказ; clear освобождает native-ресурсы. Для сайта перехватите исключение и выдайте понятное сообщение без внутренних путей. True не обещает нужного качества, допустимых настроек или сохранения деталей.
Первый управляемый результат
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
$pixels = $image->getImageWidth() * $image->getImageHeight();
if (!$image->contrastStretchImage($pixels * 0.01, $pixels * 0.99)) {
throw new RuntimeException('Не удалось применить contrastStretchImage');
}
saveStretchComparison([$source, $image], 'contrast-stretch-basic.png');
$source->clear();
$image->clear();
Результат: Справа contrastStretchImage с black_point=1280 и white_point=126720 для 128000 пикселей. Первый аргумент — нижний счётчик 1%, второй — позиция 99% снизу, то есть верхний хвост 1%. Плашки демонстрируют растяжение с насыщением крайних значений; 1% не означает ровно 1280 различных изменённых пикселей из-за повторяющихся уровней. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
contrast-stretch-basic.png
Практическая задача: Растянуть картинку, не испортив контрольные полосы макета
Для каталожного макета серые и цветные образцы должны остаться пригодными к сравнению. Применяем управляемые хвосты только к области картинки и считаем популяцию после вырезки: 352×184=64768.
CropImage получает ширину 352,высоту 184 и начало x=24,y=36; setImagePage сбрасывает виртуальное смещение вырезки. CompositeImage с COMPOSITE_OVER возвращает готовую область в(24,36). Переменная $region хранит отдельный объект; координаты задаёт макет, библиотека не узнаёт предмет сама. Границы и гистограмма определяются внутри вырезки.
Счётчик вычисляется у $region после crop, поэтому N=64768. Нижняя отсечка 647.68 и верхняя позиция 64120.32 допускают дробные float-счётчики; библиотека всё равно накапливает целые количества пикселей. Не округляйте их в яркость 0..255 и не берите прежнюю площадь исходника.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
$region = clone $source;
$region->cropImage(352, 184, 24, 36);
$region->setImagePage(0, 0, 0, 0);
$pixels = $region->getImageWidth() * $region->getImageHeight();
if (!$region->contrastStretchImage($pixels * 0.01, $pixels * 0.99)) {
throw new RuntimeException('Не удалось применить contrastStretchImage');
}
if (!$image->compositeImage($region, Imagick::COMPOSITE_OVER, 24, 36)) {
throw new RuntimeException('Не удалось вернуть область');
}
$region->clear();
saveStretchComparison([$source, $image], 'contrast-stretch-region.png');
$source->clear();
$image->clear();
Результат: Справа изменена только картинка в x=24..375,y=36..219; обе нижние шкалы и все внешние пиксели сохранены. Аргументы считаются от 64768, а не 128000. Внутренний результат отличается от растяжения всего макета: служебные плашки больше не участвуют в гистограмме. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
contrast-stretch-region.png
Ошибки, ограничения и альтернативы
Числа 0.01 и 0.99 без умножения означают доли одного пикселя, а не 1% и 99%. При wrong white_point можно получить вырожденные границы или потерю почти всего диапазона. В точной C-реализации накопление сравнивается строго >; равные значения на гистограмме группируются. Для веб-настроек проверяйте конечность и 0≤black_point Основные программы используют один непрозрачный sRGB PNG. На отдельном RGBA-образце нашей сборки default этих четырёх операций менял alpha; у трёх методов с channel явная маска RED|GREEN|BLUE сохранила её. У linearStretchImage channel-аргумента нет. Для прозрачных файлов заранее выберите и проверьте самостоятельную политику alpha. Цветовые профили и многокадровые файлы также требуют отдельной обработки. Соседние методы: autoLevelImage · normalizeImage · linearStretchImage. Для яркости, контраста и gamma: гамма, яркость и контраст; для двоичного документа: пороги.
Imagick::linearStretchImageНужно задавать два хвоста одинаковым способом, например 1% снизу и 1% сверху для каталожных изображений разного размера.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::linearStretchImage(float $blackPoint, float $whitePoint): boolНужно задавать два хвоста одинаковым способом, например 1% снизу и 1% сверху для каталожных изображений разного размера.

Самая маленькая запись
Первая строка перемножает текущие ширину и высоту и сохраняет популяцию в $pixels. У 400×320 получается 128000. Во второй строке два аргумента равны 1280: 1% пикселей от тёмного края и 1% от светлого. Второй аргумент здесь не верхняя позиция 99%, как у contrastStretchImage. Стрелка вызывает метод объекта; круглые скобки содержат аргументы, точка с запятой завершает команду. До изменения создайте $image = clone $source: присваивание без clone оставило бы два имени одного объекта.
$pixels = $image->getImageWidth() * $image->getImageHeight();
$image->linearStretchImage($pixels * 0.01, $pixels * 0.01);Это поясняющий фрагмент. Полная программа ниже загрузит переносимый вход, проверит возврат и сохранит PNG. Основы: объект и метод, копирование, аргумент вызова.
Сигнатура и параметры
Imagick::linearStretchImage(float $blackPoint, float $whitePoint): boolОба float — численные счётчики хвостов. Первый накопляется от тёмного края, второй от светлого. Для долей a и b: linearStretchImage(a×N,b×N). В точной реализации формируется гистограмма интенсивности, выбираются границы и выполняется LevelImage с gamma=1; вне границ значения насыщаются.
| Аргумент | Смысл, единицы и default |
|---|---|
| $blackPoint | Обязательный float по официальной сигнатуре: популяция от тёмного края. Для 1% изображения 400×320 передаём 1280. Reflection этой версии использует имя black_point; примеры позиционные. |
| $whitePoint | Обязательный float: популяция от светлого края. Для верхнего 1% передаём те же 1280; не 126720. Reflection использует имя white_point. Параметра channel у метода нет. |
Возвращаемое значение, версии и отказ
Возвращается bool: true при успехе. Метод меняет пиксели текущего объекта Imagick; $ok = $image->linearStretchImage(...) сохранит флаг, не новую картинку. Доступность по PHP Manual: PECL imagick 2, PECL imagick 3. Обязательные параметры и default сохранены в сигнатуре выше.
Хотя у этих страниц нет отдельного описания ошибок, точная обвязка и preflight подтверждают ImagickException на пустом изображении и преобразование native-отказа в исключение. Чтение и запись могут отказать отдельно. В полном коде ! означает «вернулся false», throw создаёт отказ; clear освобождает native-ресурсы. Для сайта перехватите исключение и выдайте понятное сообщение без внутренних путей. True не обещает нужного качества, допустимых настроек или сохранения деталей.
Первый управляемый результат
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
$pixels = $image->getImageWidth() * $image->getImageHeight();
if (!$image->linearStretchImage($pixels * 0.01, $pixels * 0.01)) {
throw new RuntimeException('Не удалось применить linearStretchImage');
}
saveStretchComparison([$source, $image], 'linear-stretch-basic.png');
$source->clear();
$image->clear();
Результат: Справа linearStretchImage с blackPoint=1280 и whitePoint=1280. Оба аргумента здесь — счётчики хвостов: снизу и сверху. Это другая запись, чем white_point=126720 у contrastStretchImage. На этом входе редкие выбросы отсекаются, а средние уровни растягиваются; результат оцениваем по сохранённому PNG. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 800×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
linear-stretch-basic.png
Практическая задача: Сохранить долю отсечки при двух размерах каталожного превью
Сервис делает полноразмерную картинку и уменьшенное превью. Одинаковый счётчик отсечки на 400×320 и 200×160 означал бы разные доли. Для каждой копии пересчитываем площадь после resize; уменьшенное превью увеличиваем обратно только для удобного просмотра рядом.
ResizeImage получает ширину, высоту, фильтр и коэффициент blur. FILTER_BOX при уменьшении агрегирует исходные значения; после уменьшения getImageWidth/getImageHeight возвращают 200 и 160. Площадь теперь 32000 пикселей; 1% — счётчик 320. Вторая операция FILTER_POINT увеличивает обработанный растр для сравнения без сглаживания. В исходной служебной задаче сохраните 200×160 как отдельное превью; увеличение здесь нужно только для равных по размеру панелей.
<?php
declare(strict_types=1);
require __DIR__ . '/stretch-fixture.php';
$source = loadStretchSource();
$image = clone $source;
$pixels = $image->getImageWidth() * $image->getImageHeight();
if (!$image->linearStretchImage($pixels * 0.01, $pixels * 0.01)) {
throw new RuntimeException('Не удалось применить linearStretchImage');
}
$small = clone $source;
$small->resizeImage(200, 160, Imagick::FILTER_BOX, 1);
$smallPixels = $small->getImageWidth() * $small->getImageHeight();
if (!$small->linearStretchImage($smallPixels * 0.01, $smallPixels * 0.01)) {
throw new RuntimeException('Не удалось применить linearStretchImage');
}
$small->resizeImage(400, 320, Imagick::FILTER_POINT, 1);
saveStretchComparison([$source, $image, $small], 'linear-stretch-two-sizes.png');
$source->clear();
$image->clear();
$small->clear();
Результат: Панели: исходник 400×320, линейное растяжение с хвостами 1280/1280, результат 200×160 с хвостами 320/320, показанный в масштабе 2× без сглаживания. Доля в обоих вариантах 1%, но пиксели не обязаны совпасть: уменьшение меняет значения и гистограмму. Последнее увеличение не возвращает утраченную детализацию. Архив содержит example.php, stretch-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в папке с правом записи и PHP/Imagick. Помощник проверит SHA256 и восстановит точный source.png без интернета и шрифтов при запуске; итоговый PNG откройте обычным просмотрщиком. Первая панель — исходник, далее варианты в указанном порядке. Размер PNG 1200×320, каждая показанная панель 400×320; изменение рабочего разрешения отдельно объяснено в примере.
Ожидаемый вывод
linear-stretch-two-sizes.png
Ошибки, ограничения и альтернативы
В C используется накопление >=, поэтому граница при точном равенстве счётчика может отличаться от contrastStretchImage. Один выброс и счётчик ровно 1 среди ста пикселей ещё выбирают этот выброс; это видно в отдельной проверке. На ровной плашке текущий linearStretch вернул true и сделал чёрный при совпавших границах; uniform-вход следует распознать и пропустить по политике приложения. Аргументы не являются числами 0..255 и не проверяют качество сами.
Прикладная валидация: оба счётчика a и b должны быть конечными, a≥0, b≥0 и a+b<N. Это разумная политика приложения, а не обещание встроенной проверки Imagick. Отдельно проверьте ненулевой рабочий диапазон; даже корректные доли не создают детали на однотонном входе.
Основные программы используют один непрозрачный sRGB PNG. На отдельном RGBA-образце нашей сборки default этих четырёх операций менял alpha; у трёх методов с channel явная маска RED|GREEN|BLUE сохранила её. У linearStretchImage channel-аргумента нет. Для прозрачных файлов заранее выберите и проверьте самостоятельную политику alpha. Цветовые профили и многокадровые файлы также требуют отдельной обработки.
Соседние методы: autoLevelImage · normalizeImage · contrastStretchImage. Для яркости, контраста и gamma: гамма, яркость и контраст; для двоичного документа: пороги.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


