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

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

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

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

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

Imagick: пороги, неравномерная бумага и отсечки полутонов

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

От накладной к первому чёрно-белому PNG

Скан накладной нужно сделать удобнее для просмотра: оставить тёмные буквы, отделить их от бумаги или убрать только крайние серые значения. Начнём с собственного учебного изображения: бумага слева затемнена, справа светлее, одинаковые слова стоят в обеих колонках. Внизу пять плашек 50, 80, 128, 170 и 220 по шкале 0..255. Это нарисованный учебный вход, не фотография реального документа.

Собственная накладная 400×320: одинаковые слова, неодинаковое освещение, тонкие линии и пять точных серых плашек
Собственная накладная 400×320: одинаковые слова, неодинаковое освещение, тонкие линии и пять точных серых плашек
Один глобальный порог 50%: исходник слева, фактический двоичный результат справа; тень тоже может почернеть
Один глобальный порог 50%: исходник слева, фактический двоичный результат справа; тень тоже может почернеть

Порог — граница сравнения. Главный вызов $image->thresholdImage($quantum * 0.5); сравнивает значения с половиной диапазона. $image — переменная с объектом изображения; стрелка вызывает его метод. В скобках один аргумент, звёздочка умножает, 0.5 означает половину. Метод меняет пиксели этого объекта, точка с запятой завершает команду.

$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
$image->thresholdImage($quantum * 0.5);

Это поясняющий фрагмент: в полной программе ниже $source загружается из приложенного файла. Clone создаёт независимую копию; простое присваивание оставило бы два имени одного объекта. Imagick::getQuantumRange() возвращает массив сведений о диапазоне native-библиотеки; квадратные скобки с ключом quantumRangeLong извлекают максимум. В нашей Q16-сборке это 65535, поэтому половина равна 32767.5. У PNG8 на рисунке другая шкала: 0..255.

В saveThresholdComparison([$source, $image], 'first-threshold.png') квадратные скобки создают список двух изображений: исходник слева, копия справа. Помощник собирает полотно, пишет PNG8 и выводит имя файла. If с ! означает «если вернулся false», throw создаёт сообщение об отказе; clear после записи освобождает native-ресурсы. Подключённый помощник показан полностью в разделе о запуске.

Получить и открыть первый двоичный PNGПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->thresholdImage($quantum * 0.5)) {
    throw new RuntimeException('Не удалось применить thresholdImage');
}
saveThresholdComparison([$source, $image], 'first-threshold.png');
$source->clear();
$image->clear();

Результат: Справа порог 50%: значения 50 и 80 стали 0, а 128, 170 и 220 стали 255. Все пиксели правой панели чёрные или белые. Затемнённая бумага слева местами стала чёрной вместе с буквами: один общий порог не отделяет освещение от печати. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
first-threshold.png

Одна граница и две отсечки — разные результаты

Одна и та же шкала 50, 80, 128, 170, 220: общий порог и две односторонние отсечки решают разные задачи
Одна и та же шкала 50, 80, 128, 170, 220: общий порог и две односторонние отсечки решают разные задачи
ПотребностьОперацияЧто сохраняется
Только тёмное или светлоеthresholdImage: одна общая границаПосле полной бинаризации промежуточные значения исчезают.
Буквы на неравномерном фонеadaptiveThresholdImage: граница из окрестностиСохраняется локальное отличие, но не исходные полутона.
Почернить только самые тёмные значенияblackThresholdImage: нижняя отсечкаСредние и светлые значения остаются прежними.
Выбелить только самые светлые значенияwhiteThresholdImage: верхняя отсечкаСредние и тёмные значения остаются прежними.

Представьте проверку по линейке яркости: общий порог — одна отметка для всех; локальный — отметка, вычисленная из соседнего участка. Это модель сравнения чисел, а не понимание содержимого документа. Бумага и буква с одинаковым числом при общем пороге получат одинаковый результат. Два односторонних порога могут оставить серую середину; это не обязательно бинаризация.

Сопоставить двоичный результат, чёрную и белую отсечкуПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->thresholdImage($quantum * 0.5)) {
    throw new RuntimeException('Не удалось применить thresholdImage');
}
$black = clone $source;
if (!$black->blackThresholdImage('gray(35%)')) {
    throw new RuntimeException('Не удалось применить blackThresholdImage');
}
$white = clone $source;
if (!$white->whiteThresholdImage('gray(75%)')) {
    throw new RuntimeException('Не удалось применить whiteThresholdImage');
}
saveThresholdComparison([$source, $image, $black, $white], 'operation-controls.png');
$source->clear();
$image->clear();
$black->clear();
$white->clear();

Результат: Панели: исходник, thresholdImage 50%, blackThresholdImage 35%, whiteThresholdImage 75%. Только вторая панель целиком двоичная. Третья сохраняет 128/170/220, четвёртая сохраняет 50/80/128/170; разница проверяется по нижним плашкам. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 1600×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
operation-controls.png

Единицы, типы и переносимый запуск

Параметры похожи по названию, но имеют разные формы. ThresholdImage получает float в native-единицах: относительную долю умножаем на quantumRangeLong. AdaptiveThresholdImage получает int offset в тех же единицах; дробную долю округляем и приводим к int. BlackThresholdImage и whiteThresholdImage получают цвет: строка gray(35%) задаёт серый на 35% диапазона, а не float 0.35. Не смешивайте эти три записи.

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

Полный помощник восстановления входа и записи сравнения
<?php
declare(strict_types=1);

function loadThresholdSource(): 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) !== 'd882db9c9f736ac7ec635602887543346781f0137e86cc834bb840b994ed5ea5') {
        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 saveThresholdComparison(array $panels, string $filename): void
{
    $output = new Imagick();
    $output->newImage(400 * count($panels), 320, 'white');
    $output->setImageFormat('png');
    foreach ($panels as $index => $panel) {
        if ($panel->getImageWidth() !== 400 || $panel->getImageHeight() !== 320) {
            throw new InvalidArgumentException('Панель должна быть 400 на 320 пикселей');
        }
        if (!$output->compositeImage($panel, Imagick::COMPOSITE_OVER, 400 * $index, 0)) {
            throw new RuntimeException('Не удалось собрать сравнение');
        }
    }
    $output->setImageDepth(8);
    if (!$output->writeImage(__DIR__ . '/' . $filename)) {
        throw new RuntimeException('Не удалось записать результат');
    }
    $output->clear();
    echo $filename, "\n";
}

Помощник использует file_get_contents, base64_decode с проверкой, hash и file_put_contents для восстановления входа. CompositeImage переносит готовые панели на полотно без изменения размера; setImageDepth(8) задаёт глубину при записи. Это обвязка воспроизводимого опыта. Папка должна быть доступна для записи, расширение imagick установлено. В учебных примерах нет запуска внешней команды или шрифта: текст уже находится в пикселях PNG.

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

Почему локальный порог помогает тени и мешает заливке

Для конкретного пикселя: среднее соседей, offset в quantum-единицах, сравнение и запись 0 либо максимума
Для конкретного пикселя: среднее соседей, offset в quantum-единицах, сравнение и запись 0 либо максимума
Исходная накладная, общий 50% и окно 31×31 с отрицательным offset: фактические пиксели бумаги и штрихов
Исходная накладная, общий 50% и окно 31×31 с отрицательным offset: фактические пиксели бумаги и штрихов

Гистограмма яркости считает, сколько пикселей имеет каждый уровень. Если тёмные буквы и светлая бумага образуют две отдельные группы, между ними легче выбрать общую границу. При неодинаковом освещении группы смешиваются и выраженных пиков может не быть — именно такую ситуацию выделяет официальное описание адаптивного порога. Локальное окружение даёт более близкий ориентир для каждого участка.

В проверенной ImageMagick 7.1.1-46 локальное среднее вычисляется по каналам окна, к нему прибавляется offset. На ровной бумаге value примерно равно mean. При offset 0 равенство даёт чёрный; отрицательное смещение уменьшает границу и позволяет ровной бумаге стать белой. Для тёмной буквы значение ниже среднего с окружающей бумагой и она остаётся чёрной. Это объясняет знак, а не обещает, что −3% подходит каждому снимку.

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

Практический переход: окна 15×15 и 41×41. Размер окна не равен силе offset. Сначала измените один параметр на независимых копиях, затем выберите сочетание на нескольких реальных входах.

Граница равенства, цвет и сохранённые полутона

Пять известных значений в исходнике, после глобального порога, black 35% и white 75%: односторонние отсечки сохраняют серую середину
Пять известных значений в исходнике, после глобального порога, black 35% и white 75%: односторонние отсечки сохраняют серую середину

На сером входе правила можно записать точно: thresholdImage — value <= T превращается в 0, остальное в максимум; blackThresholdImage — value < T превращается в 0; whiteThresholdImage — value > T превращается в максимум. При точной границе rgb(128,128,128) чёрная и белая отсечки оставили 128, а общий threshold отправил равное значение в чёрный. Gray(50%) в Q16 — половина 65535, а rgb(128,128,128) — 128/255 диапазона: это близкие, но разные границы.

У цветного RGB смысл зависит от текущей маски каналов и режима интенсивности. При default в нашей сборке black/white не дали простого независимого RGB-сравнения; поэтому учебные правила и измерения выше относятся к серому входу. У thresholdImage явный CHANNEL_RED изменил только красную составляющую, сохранив зелёную и синюю. Канал — составляющая цвета у пикселей всей области; для обработки прямоугольника требуется вырезка/маска, как в примере blackThresholdImage.

Два порога 35% и 75% оставляют серую середину. Это полезно для контролируемого оформления, но не исправляет освещение. Для изменения распределения всех тонов сравните гамму и контраст. Для полного двоичного результата вернитесь к общему порогу или локальному порогу.

Выбрать критерии качества и обработать отказ

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

В своём сервисе проверьте чтение файла, допустимый формат, размер, число кадров и право записи. Параметры должны быть конечными и попадать в ваши границы; окно ограничьте до начала native-операции. Ошибка чтения, исключение фильтра и ошибка записи — разные точки отказа. Изображение с alpha, белый фон страницы и прозрачная маска требуют разных решений. Большие документы и несколько clone-копий расходуют память; начните с ограниченного разрешения и измерьте длительность своей цепочки.

Воспроизводимый результат в этой главе относится к PHP 8.5.11, Imagick 3.8.1 и ImageMagick 7.1.1-46 Q16. Официальная доступность шире, но численные детали другой библиотеки или другого редактора нельзя переносить по одному имени параметра. Все скачиваемые программы создают реальный PNG; просмотр результата является частью выбора настройки.

Сделать следующий вариант и проверить конкретные значения

Выбор по желаемому результату: двоичная копия, локальная тень или сохранённые средние тона
Выбор по желаемому результату: двоичная копия, локальная тень или сохранённые средние тона
  • Нужно только чёрное и белое при ровном фоне: начните с общего порога на независимой копии.
  • Бумага в тени мешает общему порогу: сравните локальное окно и offset на нескольких участках.
  • Нужен чистый чёрный при сохранённых светах: нижняя black-отсечка.
  • Нужен белый фон при сохранённых тенях: верхняя white-отсечка; для сохранения середины сочетайте две разные границы.

Упражнение: получить вариант с чистыми крайними значениями, сохранив плашки 128 и 170 и исходный файл. Предлагаемое решение: $image = clone $source; затем blackThresholdImage('gray(35%)') и whiteThresholdImage('gray(75%)'), сохранить новый PNG. Проверка: 50/80 стали 0, 128/170 остались прежними, 220 стало 255. Готовая программа находится в примере двух отсечек. Для двоичной копии это решение не подходит: у неё иная цель.

Дальше можно добавить собственную отметку на уже готовое изображение, сравнить осторожное размытие с потерей тонких линий или организовать запись отдельных производных файлов. Любую новую настройку сравнивайте с исходником, а не с предыдущей потерявшей полутона версией.

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

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

Imagick::thresholdImageНужны только две группы пикселей: тёмные и светлые, например перед ручной проверкой простого монохромного макета.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::thresholdImage(float $threshold, int $channel = Imagick::CHANNEL_DEFAULT): bool

Нужны только две группы пикселей: тёмные и светлые, например перед ручной проверкой простого монохромного макета.

Общий порог 40% и 60% на одном входе: тёмные пиксели и тень меняются вместе
Общий порог 40% и 60% на одном входе: тёмные пиксели и тень меняются вместе

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

В $image уже загружены пиксели. Стрелка вызывает thresholdImage; круглые скобки содержат единственный обязательный аргумент. $quantum — максимум из Imagick::getQuantumRange()['quantumRangeLong']; звёздочка умножает его на 0.5. Точка с запятой завершает вызов. На нашем входе плашка 80 станет 0, плашка 170 станет 255. Для сохранения исходника сначала создайте $image = clone $source.

$image->thresholdImage($quantum * 0.5);

Это поясняющий фрагмент текущего вызова. Полная программа далее подключает вход, создаёт clone-копию, проверяет результат и записывает сравнение; её можно скачать и запустить целиком. Перед началом: объект и метод, копирование объекта, аргумент вызова.

Сигнатура и параметры

Imagick::thresholdImage(float $threshold, int $channel = Imagick::CHANNEL_DEFAULT): bool

Один порог используется по всему изображению. В нашем сером входе значение не выше порога становится 0, выше — максимумом диапазона. Чёрное и белое здесь являются значениями пикселей, а не распознанными буквами или объектами.

АргументЗначение и единицы
$thresholdОбязательный float в единицах QuantumRange. Для 50% вычисляем $quantum * 0.5; 0.5 само по себе не означает половину диапазона Q16.
$channelНеобязательный int, default Imagick::CHANNEL_DEFAULT. Именованная константа выбирает каналы. В проверенной версии пропущенный channel даёт двоичный результат на RGB, а CHANNEL_RED меняет R, оставляя G/B исходными. Это выбор составляющей, не прямоугольной области.

Возвращаемое значение, версии и отказ

Возвращается bool: true при успехе. Метод меняет пиксели текущего Imagick; присваивание $ok = $image->thresholdImage(...) сохранит флаг, а не новую картинку. Для независимого исходника используйте clone до изменения. Доступность по официальному мануалу: PECL imagick 2, PECL imagick 3. Все параметры обязательны, кроме явно указанного channel у thresholdImage.

В проверенной Imagick 3.8.1 вызов на пустом объекте даёт ImagickException; сбой самой операции ImageMagick обвязка также превращает в исключение. Чтение входа и запись PNG могут отказать отдельно. В CLI необработанное исключение завершит программу; в веб-обработчике перехватите его и выдайте понятную ошибку без абсолютных путей. True подтверждает выполнение операции, качество оценивается по изображению.

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

Получить двоичный вариант накладнойПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->thresholdImage($quantum * 0.5)) {
    throw new RuntimeException('Не удалось применить thresholdImage');
}
saveThresholdComparison([$source, $image], 'threshold-global.png');
$source->clear();
$image->clear();

Результат: Справа порог 50%: значения 50 и 80 стали 0, а 128, 170 и 220 стали 255. Все пиксели правой панели чёрные или белые. Затемнённая бумага слева местами стала чёрной вместе с буквами: один общий порог не отделяет освещение от печати. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
threshold-global.png

Практическая задача: Сравнить общий порог 40% и 60% перед сохранением копии

Нужно выбрать, какие слабые штрихи попадут в двоичный вариант. Делаем две независимые копии исходника, чтобы второй результат показывал другой порог, а не повторную обработку уже чёрно-белых пикселей.

Сравнить общий порог 40% и 60% перед сохранением копииПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->thresholdImage($quantum * 0.4)) {
    throw new RuntimeException('Не удалось применить thresholdImage');
}
$higher = clone $source;
if (!$higher->thresholdImage($quantum * 0.6)) {
    throw new RuntimeException('Не удалось применить thresholdImage');
}
saveThresholdComparison([$source, $image, $higher], 'global-levels.png');
$source->clear();
$image->clear();
$higher->clear();

Результат: Слева исходник, в центре 40%, справа 60%. При 40% плашка 128 белая, при 60% чёрная; число чёрных пикселей справа больше. Увеличение порога сохраняет больше тёмных деталей, но одновременно захватывает больше затемнённой бумаги. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 1200×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
global-levels.png

Ошибки, ограничения и альтернативы

Порог не подстраивается под тень: одна и та же бумага может пересечь общую границу. Повышение порога делает больше пикселей чёрными. Явный CHANNEL_RED может оставить цветной результат, поэтому обещание «двухцветный» нельзя переносить на произвольную выборку каналов. Для обычного монохромного документа заранее выберите политику преобразования цвета в серый; учебный вход уже серый.

Эти программы работают с одним непрозрачным серым RGB PNG. Цветовые профили, CMYK, HDR, alpha и анимация требуют самостоятельной политики. Изменённые значения теряются: противоположная отсечка не восстановит исходник. Сохраняйте оригинал и сравнивайте при одинаковом масштабе. Порог не гарантирует распознавания, удаления шума или сохранения каждой тонкой линии.

Соседние инструменты: adaptiveThresholdImage · blackThresholdImage · whiteThresholdImage. Далее: тональный контраст и гамма, шум, размытие и резкость.

Imagick::adaptiveThresholdImageТёмные буквы находятся на бумаге с разной освещённостью, поэтому один общий порог захватывает теневой фон.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::adaptiveThresholdImage(int $width, int $height, int $offset): bool

Тёмные буквы находятся на бумаге с разной освещённостью, поэтому один общий порог захватывает теневой фон.

Исходник, общий порог и адаптивное сравнение: локальный метод учитывает окружающую бумагу
Исходник, общий порог и адаптивное сравнение: локальный метод учитывает окружающую бумагу

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

В $image находится копия загруженного серого изображения, $quantum — максимум его native-диапазона. Первая строка умножает максимум на −0.03; round округляет число, (int) приводит его к целому, знак = сохраняет результат в переменной $offset. При Q16 получится −1966. Во второй строке стрелка вызывает метод, запятые отделяют ширину окна 31, высоту 31 и смещение. Точки с запятой завершают команды. На нашем входе фон в двух контрольных точках станет белым, буквы в обеих колонках останутся видимыми.

$offset = (int) round(-0.03 * $quantum);
$image->adaptiveThresholdImage(31, 31, $offset);

Это поясняющий фрагмент текущего вызова. Полная программа далее подключает вход, создаёт clone-копию, проверяет результат и записывает сравнение; её можно скачать и запустить целиком. Перед началом: объект и метод, копирование объекта, аргумент вызова.

Сигнатура и параметры

Imagick::adaptiveThresholdImage(int $width, int $height, int $offset): bool

Для каждого пикселя вычисляется среднее в соседнем окне и добавляется offset. В ImageMagick 7.1.1-46 сравнение имеет вид value <= localMean + offset: тогда записывается 0, иначе QuantumRange. Отрицательный offset уменьшает локальный порог; это направление противоположно привычному положительному C в некоторых других библиотеках.

АргументЗначение и единицы
$widthОбязательный int: ширина локального окна в пикселях текущего изображения, в примерах 15, 31 или 41. Это не ширина выходного файла.
$heightОбязательный int: высота окна в пикселях. Берём положительные нечётные размеры для симметричного расположения соседей вокруг текущего пикселя.
$offsetОбязательный int в единицах QuantumRange, без default. Здесь (int) round(-0.03 * $quantum) даёт −1966 при Q16=65535, приблизительно −7.65 по шкале 0..255. Это не −3 пикселя и не −3 уровня PNG8.

Возвращаемое значение, версии и отказ

Возвращается bool: true при успехе. Метод меняет пиксели текущего Imagick; присваивание $ok = $image->adaptiveThresholdImage(...) сохранит флаг, а не новую картинку. Для независимого исходника используйте clone до изменения. Доступность по официальному мануалу: PECL imagick 2, PECL imagick 3. Все параметры обязательны, кроме явно указанного channel у thresholdImage.

В проверенной Imagick 3.8.1 вызов на пустом объекте даёт ImagickException; сбой самой операции ImageMagick обвязка также превращает в исключение. Чтение входа и запись PNG могут отказать отдельно. В CLI необработанное исключение завершит программу; в веб-обработчике перехватите его и выдайте понятную ошибку без абсолютных путей. True подтверждает выполнение операции, качество оценивается по изображению.

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

Отделить тёмные буквы от неравномерно освещённой бумагиПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
$offset = (int) round(-0.03 * $quantum);
if (!$image->adaptiveThresholdImage(31, 31, $offset)) {
    throw new RuntimeException('Не удалось применить adaptiveThresholdImage');
}
saveThresholdComparison([$source, $image], 'adaptive-local.png');
$source->clear();
$image->clear();

Результат: Справа локальное окно 31×31 и offset −1966 в проверенной Q16-сборке. Бумага в контрольных точках (8,110) и (390,110) стала белой; тёмные штрихи в обеих колонках сохранились. Результат двоичный; нижние большие серые плашки показывают, почему локальный метод не предназначен для сохранения сплошных полутоновых областей. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
adaptive-local.png

Практическая задача: Выбрать размер локального окна для букв и тонких линий

Одинаковые буквы расположены в тени и на свету. Сравним окно 15×15 и 41×41 при одном offset: изменяется только область соседей, из которой вычисляется среднее.

Выбрать размер локального окна для букв и тонких линийПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
$offset = (int) round(-0.03 * $quantum);
if (!$image->adaptiveThresholdImage(15, 15, $offset)) {
    throw new RuntimeException('Не удалось применить adaptiveThresholdImage');
}
$wider = clone $source;
if (!$wider->adaptiveThresholdImage(41, 41, $offset)) {
    throw new RuntimeException('Не удалось применить adaptiveThresholdImage');
}
saveThresholdComparison([$source, $image, $wider], 'adaptive-windows.png');
$source->clear();
$image->clear();
$wider->clear();

Результат: В центре окно 15×15, справа 41×41. Панели различаются реальными пикселями: окружающая бумага и края крупных серых плашек участвуют в среднем на разной площади. Оба варианта двоичные и сохраняют белую бумагу в двух контрольных точках; выбирайте по читаемости нужных штрихов, а не по размеру файла. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 1200×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
adaptive-windows.png

Ошибки, ограничения и альтернативы

Нечётный положительный размер — явная политика этих примеров, а не универсальная native-проверка: в текущей библиотеке 2×2 принимается, нулевой width или height возвращает неизменённую копию. В приложении отклоняйте нулевые/отрицательные/слишком большие размеры до native-вызова. Маленькое окно может потерять внутренность толстой заливки; большое захватывает другую освещённость. На границах используются виртуальные пиксели библиотеки. Метод не знает, где текст, и не выполняет OCR.

Эти программы работают с одним непрозрачным серым RGB PNG. Цветовые профили, CMYK, HDR, alpha и анимация требуют самостоятельной политики. Изменённые значения теряются: противоположная отсечка не восстановит исходник. Сохраняйте оригинал и сравнивайте при одинаковом масштабе. Порог не гарантирует распознавания, удаления шума или сохранения каждой тонкой линии.

Соседние инструменты: thresholdImage · blackThresholdImage · whiteThresholdImage. Далее: тональный контраст и гамма, шум, размытие и резкость.

Imagick::blackThresholdImageТёмные буквы нужно сделать чёрными, сохранив светлую бумагу и серые заливки.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::blackThresholdImage(mixed $threshold): bool

Тёмные буквы нужно сделать чёрными, сохранив светлую бумагу и серые заливки.

Общий порог, чёрная и белая отсечки: средние плашки остаются серыми только в нужных вариантах
Общий порог, чёрная и белая отсечки: средние плашки остаются серыми только в нужных вариантах

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

В $image уже находятся пиксели отдельной копии. Стрелка вызывает blackThresholdImage, а один аргумент в круглых скобках — строка цвета. Кавычки ограничивают строку; gray(35%) внутри неё обозначает серую границу 35%, а не ещё один вызов PHP-функции. Точка с запятой завершает команду. На нашем входе 50 и 80 станут 0, а 128, 170 и 220 сохранятся. Без предварительного clone изменился бы сам исходный объект.

$image->blackThresholdImage('gray(35%)');

Это поясняющий фрагмент текущего вызова. Полная программа далее подключает вход, создаёт clone-копию, проверяет результат и записывает сравнение; её можно скачать и запустить целиком. Перед началом: объект и метод, копирование объекта, аргумент вызова.

Сигнатура и параметры

Imagick::blackThresholdImage(mixed $threshold): bool

Значения строго ниже нижней границы становятся чёрными; остальные остаются прежними. В отличие от thresholdImage светлая сторона не принуждается к белому. Наши серые плашки позволяют проверить это напрямую.

АргументЗначение и единицы
$thresholdОбязательный mixed в официальном мануале: практически передавайте строку цвета, например gray(35%), либо ImagickPixel с этим цветом. В проверенной Reflection указан ImagickPixel|string и имя threshold_color. Здесь используем позиционный вызов; numeric 128 и 0.5 не являются корректным способом задать quantum-порог.

Возвращаемое значение, версии и отказ

Возвращается bool: true при успехе. Метод меняет пиксели текущего Imagick; присваивание $ok = $image->blackThresholdImage(...) сохранит флаг, а не новую картинку. Для независимого исходника используйте clone до изменения. Доступность по официальному мануалу: PECL imagick 2, PECL imagick 3. Все параметры обязательны, кроме явно указанного channel у thresholdImage.

Изменение PECL imagick 2.1.0: разрешена строка, представляющая цвет; более ранние версии принимали только объект ImagickPixel. Примеры выполнены с Imagick 3.8.1. При переносе кода учитывайте версию расширения и поддерживаемую форму аргумента.

В проверенной Imagick 3.8.1 вызов на пустом объекте даёт ImagickException; сбой самой операции ImageMagick обвязка также превращает в исключение. Чтение входа и запись PNG могут отказать отдельно. В CLI необработанное исключение завершит программу; в веб-обработчике перехватите его и выдайте понятную ошибку без абсолютных путей. True подтверждает выполнение операции, качество оценивается по изображению.

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

Сделать тёмные штрихи чёрными, сохранив светлые полутонаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->blackThresholdImage('gray(35%)')) {
    throw new RuntimeException('Не удалось применить blackThresholdImage');
}
saveThresholdComparison([$source, $image], 'black-threshold.png');
$source->clear();
$image->clear();

Результат: Справа только значения ниже 35% стали чёрными. Плашки 50 и 80 стали 0, а 128, 170 и 220 остались без изменений. Светлая бумага и средние тона сохраняются: это ещё не двоичное изображение. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
black-threshold.png

Практическая задача: Усилить чёрный только внутри известной области документа

Контрольную серую шкалу и поля требуется оставить как в оригинале. Вырезаем прямоугольник с документом, применяем blackThresholdImage с объектом цвета и возвращаем обработанную область на независимую исходную копию.

CropImage получает ширину 360, высоту 230 и координаты x=20,y=20; setImagePage сбрасывает смещение вырезки. New ImagickPixel создаёт объект цвета. После обработки compositeImage возвращает прямоугольник на прежнее место. Выбирается известная геометрия накладной; метод не находит поля сам.

Усилить чёрный только внутри известной области документаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
$region = clone $source;
$region->cropImage(360, 230, 20, 20);
$region->setImagePage(0, 0, 0, 0);
$limit = new ImagickPixel('gray(35%)');
if (!$region->blackThresholdImage($limit)) {
    throw new RuntimeException('Не удалось применить blackThresholdImage');
}
if (!$image->compositeImage($region, Imagick::COMPOSITE_OVER, 20, 20)) {
    throw new RuntimeException('Не удалось вернуть область');
}
$limit->clear();
$region->clear();
saveThresholdComparison([$source, $image], 'black-document-region.png');
$source->clear();
$image->clear();

Результат: Справа изменён только прямоугольник x=20..379, y=20..249. Все пиксели снаружи совпадают с исходником, включая пять нижних плашек. Внутри значения ниже 35% почернели; остальные сохранены. Граница задана координатами, а не распознаванием текста. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
black-document-region.png

Ошибки, ограничения и альтернативы

Слово mixed не разрешает произвольный тип. В проверенной сборке массив, null, bool, чужой объект и некорректная строка вызывают ImagickException. Числа 128/0.5 также отклонены как нераспознанный цвет. Значение ровно на границе не обрезается. На цветном RGB при default правила зависят от интенсивности и маски каналов, поэтому не считайте это безусловным независимым сравнением каждой R/G/B-компоненты. Для предсказуемого документа сначала выберите серое представление.

Эти программы работают с одним непрозрачным серым RGB PNG. Цветовые профили, CMYK, HDR, alpha и анимация требуют самостоятельной политики. Изменённые значения теряются: противоположная отсечка не восстановит исходник. Сохраняйте оригинал и сравнивайте при одинаковом масштабе. Порог не гарантирует распознавания, удаления шума или сохранения каждой тонкой линии.

Соседние инструменты: thresholdImage · adaptiveThresholdImage · whiteThresholdImage. Далее: тональный контраст и гамма, шум, размытие и резкость.

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

PECL imagick 2, PECL imagick 3 · imagick

Imagick::whiteThresholdImage(mixed $threshold): bool

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

Исходник, общий порог, чёрная и белая отсечки: светлые значения меняются отдельно от середины
Исходник, общий порог, чёрная и белая отсечки: светлые значения меняются отдельно от середины

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

В $image загружена независимая копия серого входа. Стрелка вызывает метод объекта, круглые скобки содержат строку цвета. Кавычки обозначают буквальный текст gray(75%), который библиотека разбирает как серую границу на 75% диапазона. Точка с запятой завершает команду. На нашем входе 220 станет 255, а 50, 80, 128 и 170 останутся прежними. Полный пример ниже также загрузит и сохранит PNG.

$image->whiteThresholdImage('gray(75%)');

Это поясняющий фрагмент текущего вызова. Полная программа далее подключает вход, создаёт clone-копию, проверяет результат и записывает сравнение; её можно скачать и запустить целиком. Перед началом: объект и метод, копирование объекта, аргумент вызова.

Сигнатура и параметры

Imagick::whiteThresholdImage(mixed $threshold): bool

Значения строго выше верхней границы становятся белыми; остальные сохраняются. Совместно с blackThresholdImage можно обрезать оба края и оставить среднюю часть диапазона без растяжения.

АргументЗначение и единицы
$thresholdОбязательный mixed в официальной сигнатуре. Используйте строку цвета gray(75%) или ImagickPixel. У аргумента нет default. В проверенной Reflection тип ImagickPixel|string, имя threshold_color. 75% внутри цветовой строки — доля диапазона цвета, в отличие от float-аргумента thresholdImage.

Возвращаемое значение, версии и отказ

Возвращается bool: true при успехе. Метод меняет пиксели текущего Imagick; присваивание $ok = $image->whiteThresholdImage(...) сохранит флаг, а не новую картинку. Для независимого исходника используйте clone до изменения. Доступность по официальному мануалу: PECL imagick 2, PECL imagick 3. Все параметры обязательны, кроме явно указанного channel у thresholdImage.

Изменение PECL imagick 2.1.0: разрешена строка, представляющая цвет; более ранние версии принимали только объект ImagickPixel. Примеры выполнены с Imagick 3.8.1. При переносе кода учитывайте версию расширения и поддерживаемую форму аргумента.

В проверенной Imagick 3.8.1 вызов на пустом объекте даёт ImagickException; сбой самой операции ImageMagick обвязка также превращает в исключение. Чтение входа и запись PNG могут отказать отдельно. В CLI необработанное исключение завершит программу; в веб-обработчике перехватите его и выдайте понятную ошибку без абсолютных путей. True подтверждает выполнение операции, качество оценивается по изображению.

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

Выбелить светлую бумагу без почернения буквПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->whiteThresholdImage('gray(75%)')) {
    throw new RuntimeException('Не удалось применить whiteThresholdImage');
}
saveThresholdComparison([$source, $image], 'white-threshold.png');
$source->clear();
$image->clear();

Результат: Справа только значения выше 75% стали белыми. Плашка 220 стала 255, а 50, 80, 128 и 170 сохранились. Тёмная левая бумага не стала светлой автоматически: её значения ниже выбранного порога. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
white-threshold.png

Практическая задача: Обрезать оба края диапазона, оставив средние тона

Для иллюстрации требуется чистый чёрный в тенях и чистый белый в светах, но серые заливки должны остаться серыми. Последовательно задаём нижнюю границу 35% и верхнюю 75%, не сводя их в один общий порог.

Сначала применяется нижняя отсечка, затем верхняя. Две границы оставляют интервал 35..75% без изменения. $limit — объект с цветом верхней границы; стрелка перед clear относится к этому объекту. Для сравнения с иной настройкой снова клонируйте исходник.

Обрезать оба края диапазона, оставив средние тонаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/threshold-fixture.php';
$source = loadThresholdSource();
$image = clone $source;
$quantum = Imagick::getQuantumRange()['quantumRangeLong'];
if (!$image->blackThresholdImage('gray(35%)')) {
    throw new RuntimeException('Не удалось применить blackThresholdImage');
}
$limit = new ImagickPixel('gray(75%)');
if (!$image->whiteThresholdImage($limit)) {
    throw new RuntimeException('Не удалось применить whiteThresholdImage');
}
$limit->clear();
saveThresholdComparison([$source, $image], 'black-white-threshold.png');
$source->clear();
$image->clear();

Результат: Справа плашки 50 и 80 стали 0, плашка 220 стала 255; 128 и 170 сохранились. Между порогами остаются полутона. Это обрезание крайних значений, а не растяжение всех промежуточных тонов и не двоичная маска. Архив содержит example.php, threshold-fixture.php и source.png.b64. Распакуйте все три файла рядом и выполните php example.php в доступной для записи папке с PHP/Imagick. Помощник восстановит точный исходный source.png без интернета и без шрифтов во время запуска; итоговый PNG откройте обычным просмотрщиком. Слева исходник, далее варианты в указанном порядке. Подписи на поясняющих рисунках добавлены отдельно. Размер PNG 800×320; каждая панель 400×320 без масштабирования.

Ожидаемый вывод
black-white-threshold.png

Ошибки, ограничения и альтернативы

Равное порогу значение сохраняется. Световая отсечка не высветляет весь теневой фон и не увеличивает все значения пропорционально. Цветной вход и выбор каналов требуют отдельной проверки; пример работает с непрозрачным серым RGB. Некорректный цвет/тип и пустое изображение дают ImagickException в проверенной сборке. Для полноценного изменения гаммы/контраста нужен другой инструмент.

Эти программы работают с одним непрозрачным серым RGB PNG. Цветовые профили, CMYK, HDR, alpha и анимация требуют самостоятельной политики. Изменённые значения теряются: противоположная отсечка не восстановит исходник. Сохраняйте оригинал и сравнивайте при одинаковом масштабе. Порог не гарантирует распознавания, удаления шума или сохранения каждой тонкой линии.

Соседние инструменты: thresholdImage · adaptiveThresholdImage · blackThresholdImage. Далее: тональный контраст и гамма, шум, размытие и резкость.

Источники и обсуждения

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

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

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

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