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

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

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

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

Глава 346 · После загрузки изображения

Imagick: тусклый диапазон, выбросы и управляемое растяжение

От первого автоматического PNG до гистограммы, разных единиц двух stretchAPI, защищённых шкал, выбранного канала и двух размеров превью.

От тусклого макета к первому PNG

Каталожная иллюстрация после неудачного экспорта стала сероватой и тусклой. Нужно подготовить более различимый вариант, сохранив оригинал и понимая, какие детали могут исчезнуть. Начнём с одного PNG: рядом будут исходник и автоматические уровни. Затем сравним устойчивость к редким выбросам, управляемые хвосты, отдельный канал и превью другого размера.

Собственный тусклый макет 400×320: основные RGB-компоненты 70..190, пять точных серых уровней и две маленькие крайние метки 20/230
Собственный тусклый макет 400×320: основные RGB-компоненты 70..190, пять точных серых уровней и две маленькие крайние метки 20/230
Первое автоматическое растяжение: две крайние метки ограничивают полезный диапазон коробки и кружки
Первое автоматическое растяжение: две крайние метки ограничивают полезный диапазон коробки и кружки

Главная запись $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/maxautoLevelImageДаже одна крайняя точка участвует в границе.
Готовая политика выбросов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 будут созданы в полной программе. Стрелка вызывает метод соответствующего объекта, запятая отделяет аргументы, звёздочка умножает, точка с запятой завершает действие. На рисунке порядок панелей совпадает с порядком списка в помощнике.

Сравнить min/max и три политики хвостовПример для указанного окружения
<?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=128000contrastStretchImagelinearStretchImage
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, файлы, исключения.

Отделить выбросы от полезной детали

Выбросы по 36 пикселей против полезной картинки: метод min/max не знает назначения этих точек
Выбросы по 36 пикселей против полезной картинки: метод min/max не знает назначения этих точек
Для защиты служебных шкал выбираем область и считаем её собственную популяцию
Для защиты служебных шкал выбираем область и считаем её собственную популяцию

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

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

Не спутать область, цветовой канал и alpha

Нормализация только R меняет цвет, даже если исходная контрольная плашка серая
Нормализация только R меняет цвет, даже если исходная контрольная плашка серая

Канал — составляющая пикселя, а не предмет определённого цвета. Маска 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

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

Нормализация всех составляющих и только R: сохранение G/B проверяется отдельно
Нормализация всех составляющих и только R: сохранение G/B проверяется отдельно

Самая маленькая запись

В $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 не обещает нужного качества, допустимых настроек или сохранения деталей.

Первый управляемый результат

Явно выбрать отсечение 1% с каждого краяПример для указанного окружения
<?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% сверху для каталожных изображений разного размера.

Одна доля хвоста для двух разрешений: число пикселей пересчитывается после resize
Одна доля хвоста для двух разрешений: число пикселей пересчитывается после resize

Самая маленькая запись

Первая строка перемножает текущие ширину и высоту и сохраняет популяцию в $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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.