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

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

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

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

Глава 367 · После объектов, массивов и изображения

Imagick: глубина компонентов и реальные уровни градиента

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

Сохранить копию и увидеть ступени градиента

Нужна PNG-копия каталога для обычного просмотра, но есть точный 16 битный мастер с плавными переходами. Сохраним отдельную 8 битную копию и рядом покажем, почему дальнейшее огрубление до 4 бит даёт заметные ступени. Мастер не заменяем. Все панели на странице — реальные 8 битные просмотры PHP; точные 16 битные файлы сохраняются отдельно и проверяются по собственным значениям.

Надписи RGB16,352 отсчётов и 0…65535 нарисованы в исходном учебном PNG16. Они остаются на 8 битном просмотре и не являются метаданными этого файла.352 — число точек нашего конкретного градиента, а не предел 16 битной глубины.

Первый PHP-код: восьмибитный просмотр собственного RGB16 входа,400×320
Первый PHP-код: восьмибитный просмотр собственного RGB16 входа,400×320
Только первый код: источник,PNG8 и видимые ступени четырёхбитной сетки
Только первый код: источник,PNG8 и видимые ступени четырёхбитной сетки
До моделиКонкретный смысл
RGB / RGBARGB — красная/зелёная/синяя компоненты. A — alpha:0 прозрачен,1 непрозрачен. В Q16 целые значения компоненты от 0 до Q=65535. Входной PNG16 содержит настоящие значения между соседними восьмибитными уровнями.
Бит и сеткаd — число бит точности компоненты.2^d — максимальное число её возможных уровней:4→16,8→256,16→65536. ^ в математике — степень, не PHP XOR. Это не число цветов всей RGB-картинки и не утверждение, что все уровни заняты.
Три разных числаПоле depth текущего объекта; сетка реально присутствующих значений; bit depth в заголовке PNG. Getter читает первое. Изменение контейнера может поменять поле, не вернуть утраченную информацию.
Модель c→c′c — значение одной компоненты, c′ — результат. n — целый номер уровня. floor округляет вниз:floor(2.9)=2. Для этой Q16 nonHDRI сборки при d=4 сетка имеет шаг 4369, при d=8 —257. Способ приведения отличается от выбора ближайшего значения.
Просмотр и точные файлыPNG для просмотра имеет 8 бит на компоненту для просмотра. PNG16 с точными значениями хранит точные отсчёты для проверки. Увеличенные фрагменты повторяют реальные пиксели; они не изображают новые рассчитанные оттенки.
ВозвратДва метода установки меняют тот же объект и дают bool-статус. Getter возвращает int. Вызов метода не равен записи файла.
Поле depth, фактическая сетка значений и 8/16 битный PNG-контейнер проверяются отдельно
Поле depth, фактическая сетка значений и 8/16 битный PNG-контейнер проверяются отдельно

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$copy = clone $image;
$ok = $copy->setImageDepth(4);

В проверенной Q16-сборке это огрубляет разрешённые к изменению каналы. Возвращённое true — статус, а не новое изображение.4 означает максимум 16 уровней на компоненту, не 16 цветов RGB: комбинаций может быть больше. Для градиента это намеренный контрпример со ступеньками.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Перед программой: <?php открывает PHP, declare(strict_types=1) включает строгие типы; require подключает depth-fixture.php из папки __DIR__. Квадратные скобки принимают два изображения из loadDepthInputs: RGB16 каталог и RGBA16 наклейку. Helper восстанавливает объявленные PNG из Base64 и проверяет SHA. saveDepthPNG выбирает контейнер 8/16 через явные настройки PNG, пишет файл и возвращает вновь открытый объект; три изучаемых метода внутри helper не вызываются. saveDepthComparison размещает полные панели без изменения масштаба. Изменение bit depth для просмотра может скрыть тонкие 16 битные различия; это не доказательство равенства точных исходных отсчётов.

В первом коде $storage — отдельная копия с уже огрублёнными значениями. Явный setImageDepth(16) готовит поле этой копии к 16 битному сохранению; он не возвращает потерянные уровни. $coarse остаётся с getter4. Открытые функции helper и их ограничения приведены в разделе проверки.

Сделать восьмибитную PNG-копию и увидеть цену четырёхбитной сетки

Полные панели: восьмибитный просмотр исходного RGB16; самостоятельный PNG8 с предварительным снижением точности до 8; контрпример с сеткой 4 бит. Последний показывает ступени на плавном градиенте. PNG8 здесь означает по 8 бит на компоненту RGB, не индексированную палитру. coarse-storage16.png хранит огрублённые значения в 16 битном контейнере, не восстанавливая оттенки.

Сделать восьмибитную PNG-копию и увидеть цену четырёхбитной сеткиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$web = clone $source;
if (!$web->setImageDepth(8)) { throw new RuntimeException('Depth8 failed'); }
$savedWeb = saveDepthPNG($web, 'web-depth8.png', 8);
$webView = saveDepthPNG($savedWeb, 'web-preview8.png', 8);
$coarse = clone $source;
if (!$coarse->setImageDepth(4)) { throw new RuntimeException('Depth4 failed'); }
$storage = clone $coarse;
$storage->setImageDepth(16);
saveDepthPNG($storage, 'coarse-storage16.png', 16);
$coarseView = saveDepthPNG($coarse, 'coarse-preview8.png', 8);
saveDepthComparison([$sourceView, $webView, $coarseView], 'depth-first.png');
echo "depth-first.png\nweb-depth8.png\ncoarse-storage16.png\n";
printf("source=%d web=%d coarse=%d\n", $source->getImageDepth(), $web->getImageDepth(), $coarse->getImageDepth());

Полные панели: восьмибитный просмотр исходного RGB16; самостоятельный PNG8 с предварительным снижением точности до 8; контрпример с сеткой 4 бит. Последний показывает ступени на плавном градиенте. PNG8 здесь означает по 8 бит на компоненту RGB, не индексированную палитру. coarse-storage16.png хранит огрублённые значения в 16 битном контейнере, не восстанавливая оттенки. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-first.png
web-depth8.png
coarse-storage16.png
source=16 web=8 coarse=4

Не перепутать повышение числа и восстановление информации

Для 8→16 нет исходной информации, которая могла бы заполнить промежутки между уже склеенными уровнями. Сравните точные сохранённые значения, а не только внешний вид восьмибитного просмотра. Контроль 16→16 не меняет отсчёты в этой сборке.

Отделить исходные 16 бит, снижение до 8 и увеличение обратно до 16

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

Отделить исходные 16 бит, снижение до 8 и увеличение обратно до 16Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$same = clone $source; $same->setImageDepth(16);
$eight = clone $source; $eight->setImageDepth(8);
$expanded = clone $eight; $expanded->setImageDepth(16);
$sameRead = saveDepthPNG($same, 'unchanged16.png', 16);
$eightRead = saveDepthPNG($eight, 'control8.png', 8);
$expandedRead = saveDepthPNG($expanded, 'expanded16.png', 16);
$sameView = saveDepthPNG($sameRead, 'unchanged-preview8.png', 8);
$eightView = saveDepthPNG($eightRead, 'eight-preview8.png', 8);
$expandedView = saveDepthPNG($expandedRead, 'expanded-preview8.png', 8);
saveDepthComparison([$sourceView, $sameView, $eightView, $expandedView], 'depth-controls.png');
echo "depth-controls.png\nunchanged16.png\ncontrol8.png\nexpanded16.png\n";
printf("same=%d eight=%d expanded=%d\n", $same->getImageDepth(), $eight->getImageDepth(), $expanded->getImageDepth());

Исходник, установка 16 без уменьшения, снижение до 8, затем 8→16. Последние просмотры могут выглядеть одинаково: их формат просмотра сам восьмибитный. Но сохранённые 16 битные отсчёты показывают, что после 8→16 остаётся прежняя грубая сетка; исходные промежуточные значения не вернулись. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-controls.png
unchanged16.png
control8.png
expanded16.png
same=16 eight=8 expanded=16

Изменить все компоненты либо только выбранный рисунок

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$copy = clone $image;
$ok = $copy->setImageDepth(4);

В проверенной Q16-сборке это огрубляет разрешённые к изменению каналы. Возвращённое true — статус, а не новое изображение.4 означает максимум 16 уровней на компоненту, не 16 цветов RGB: комбинаций может быть больше. Для градиента это намеренный контрпример со ступеньками.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Весь градиент с сеткой 4 бит и локальная стилизация с сохранённым SKU
Весь градиент с сеткой 4 бит и локальная стилизация с сохранённым SKU

Огрубить все цветовые компоненты до четырёхбитной сетки

У текущего изображения depth=4, цвета выбраны из сетки максимум 16 уровней каждой компоненты. Для точного исследования сохранён PNG16; после чтения его getter возвращает 16. Это различие между сеткой значений, общим полем depth и числом бит хранения.

Огрубить все цветовые компоненты до четырёхбитной сеткиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$coarse = clone $source;
if (!$coarse->setImageDepth(4)) { throw new RuntimeException('Depth4 failed'); }
$storage = clone $coarse; $storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'all-four-storage16.png', 16);
$view = saveDepthPNG($loaded, 'all-four-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-all.png');
echo "depth-all.png\nall-four-storage16.png\n";
printf("live=%d stored-read=%d\n", $coarse->getImageDepth(), $loaded->getImageDepth());

У текущего изображения depth=4, цвета выбраны из сетки максимум 16 уровней каждой компоненты. Для точного исследования сохранён PNG16; после чтения его getter возвращает 16. Это различие между сеткой значений, общим полем depth и числом бит хранения. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-all.png
all-four-storage16.png
live=4 stored-read=16

Во второй задаче getImageRegion(352,132,24,88) берёт ширину/высоту и начало x/y в пикселях. Метод возвращает новый объект области. setImagePage(0,0,0,0) задаёт ей нулевое виртуальное положение. После уменьшения сетки compositeImage с OVER помещает непрозрачную область обратно в рабочую копию. Артикул лежит вне этой области. Связанный разбор: отдельные области и положение.

Применить грубую сетку только к рисунку, сохранив SKU

Меняем только рисунок 352×132 от(24,88), затем вставляем обратно. Вне прямоугольника исходные 16 битные значения, градиенты и SKU сохранены точно. Это намеренная стилизация; уменьшение точности не является повышением качества или автоматическим способом улучшить текст.

Применить грубую сетку только к рисунку, сохранив SKUПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$region = $source->getImageRegion(352, 132, 24, 88);
$region->setImagePage(0, 0, 0, 0);
if (!$region->setImageDepth(4)) { throw new RuntimeException('Region depth failed'); }
$protected = clone $source;
$protected->compositeImage($region, Imagick::COMPOSITE_OVER, 24, 88);
$loaded = saveDepthPNG($protected, 'protected16.png', 16);
$view = saveDepthPNG($loaded, 'protected-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-protected.png');
echo "depth-protected.png\nprotected16.png\n";

Меняем только рисунок 352×132 от(24,88), затем вставляем обратно. Вне прямоугольника исходные 16 битные значения, градиенты и SKU сохранены точно. Это намеренная стилизация; уменьшение точности не является повышением качества или автоматическим способом улучшить текст. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-protected.png
protected16.png

Прочитать depth и проверить путь сохранения

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$depth = $image->getImageDepth();
echo $depth;

Getter — метод чтения. Он возвращает целое поле depth: например 16 у исходного PNG16,4 после уменьшения. Это не подсчёт разных цветов и не обещание, что произвольный PNG16 содержит все 65536 уровней. После сохранения и чтения 16 битного контейнера значение может стать 16 даже при грубой сетке.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Поле depth объекта 4,PNG16 и getter16 после чтения: значения не стали исходными
Поле depth объекта 4,PNG16 и getter16 после чтения: значения не стали исходными

Прочитать depth объекта и заново открытого PNG16

Вживую getter вернул 4, после хранения PNG16 и чтения вернул 16, хотя числовые значения остались на четырёхбитной сетке. Метод читает общее поле текущего изображения, не подсчитывает использованные уровни и не доказывает происхождение точных оттенков.

Прочитать depth объекта и заново открытого PNG16Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$coarse = clone $source; $coarse->setImageDepth(4);
$live = $coarse->getImageDepth();
$storage = clone $coarse; $storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'read-container16.png', 16);
$read = $loaded->getImageDepth();
$view = saveDepthPNG($loaded, 'read-container-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-read.png');
echo "depth-read.png\nread-container16.png\n";
printf("live=%d read=%d\n", $live, $read);

Вживую getter вернул 4, после хранения PNG16 и чтения вернул 16, хотя числовые значения остались на четырёхбитной сетке. Метод читает общее поле текущего изображения, не подсчитывает использованные уровни и не доказывает происхождение точных оттенков. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-read.png
read-container16.png
live=4 read=16

Во второй практике отчёт 16→8→16 показывает, почему число 16 не является справкой о восстановлении деталей. Для проверки точность сохраняйте исходный мастер и сравнивайте реальные отсчёты. Формат просмотра сам 8 битный, поэтому одинаковые панели не доказывают равенства исходного 16 битного ряда.

Обнаружить ложное восстановление точности в маршруте 16→8→16

Три просмотра: исходник, сохранённая 8 битная копия и 16 битный контейнер после увеличения поля. Отчёт снова показывает 16, но сохранённые значения последнего файла равны восьмибитной копии, а не исходнику. Поэтому при работе с градиентами важно сохранять точный мастер, а не полагаться на одно число getter.

Обнаружить ложное восстановление точности в маршруте 16→8→16Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$eight = clone $source; $eight->setImageDepth(8);
$expanded = clone $eight; $expanded->setImageDepth(16);
$readEight = saveDepthPNG($eight, 'route-eight.png', 8);
$readExpanded = saveDepthPNG($expanded, 'route-expanded16.png', 16);
$eightView = saveDepthPNG($readEight, 'route-eight-preview8.png', 8);
$expandedView = saveDepthPNG($readExpanded, 'route-expanded-preview8.png', 8);
saveDepthComparison([$sourceView, $eightView, $expandedView], 'depth-no-restore.png');
echo "depth-no-restore.png\nroute-eight.png\nroute-expanded16.png\n";
printf("source=%d eight=%d expanded=%d\n", $source->getImageDepth(), $eight->getImageDepth(), $expanded->getImageDepth());

Три просмотра: исходник, сохранённая 8 битная копия и 16 битный контейнер после увеличения поля. Отчёт снова показывает 16, но сохранённые значения последнего файла равны восьмибитной копии, а не исходнику. Поэтому при работе с градиентами важно сохранять точный мастер, а не полагаться на одно число getter. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-no-restore.png
route-eight.png
route-expanded16.png
source=16 eight=8 expanded=16

Выбрать красную компоненту или alpha наклейки

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$copy = clone $image;
$ok = $copy->setImageChannelDepth(Imagick::CHANNEL_RED, 4);

Первый аргумент выбирает красный канал, второй задаёт 4 битную сетку. Для alpha замените константу на CHANNEL_ALPHA. Остальные каналы в наших контролях сохранены. Общее поле depth при этом всё равно стало 4; для сохранения остальных 16 битных отсчётов перед PNG16 нужно явно подготовить отдельную копию:

$storage = clone $copy;
$storage->setImageDepth(16);

На Q16 этот второй вызов меняет поле хранения, не возвращает потерянные красные значения и не меняет оставшиеся 16 битные G/B. Оригинальный $copy продолжает сообщать 4. Следующая запись helper выбирает контейнер PNG16 отдельно.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

RED4 меняет красный канал; точный PNG16 сохраняет исходные G/B
RED4 меняет красный канал; точный PNG16 сохраняет исходные G/B

Огрубить только красный канал и сохранить остальные значения

CHANNEL_RED выбирает только красную компоненту. G/B остаются исходными 16 битными значениями; результат сохраняется с явной подготовкой копии к PNG16. Установка канала всё равно меняет общее поле depth на 4, поэтому это поле не является отчётом о глубине каждого канала.

Огрубить только красный канал и сохранить остальные значенияПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$red = clone $source;
if (!$red->setImageChannelDepth(Imagick::CHANNEL_RED, 4)) { throw new RuntimeException('Red depth failed'); }
$live = $red->getImageDepth();
$storage = clone $red;
$storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'red-only16.png', 16);
$view = saveDepthPNG($loaded, 'red-only-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-red.png');
echo "depth-red.png\nred-only16.png\n";
printf("red-live=%d storage-read=%d\n", $live, $loaded->getImageDepth());

CHANNEL_RED выбирает только красную компоненту. G/B остаются исходными 16 битными значениями; результат сохраняется с явной подготовкой копии к PNG16. Установка канала всё равно меняет общее поле depth на 4, поэтому это поле не является отчётом о глубине каждого канала. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-red.png
red-only16.png
red-live=4 storage-read=16

Alpha задаёт смешивание с фоном, а не яркость RGB. OVER накладывает слой на непрозрачную подложку: при A=0 виден фон, при A=1 — слой, промежуточные значения смешивают цвета. В этой задаче выбираем только CHANNEL_ALPHA, сохраняем RGB и оба конца alpha. Тёмный/светлый фон относится к отдельным PNG-просмотрам; raw RGBA-файл хранит прозрачность без подложки.

Исходная alpha и её четырёхбитная сетка на явно заданных подложках
Исходная alpha и её четырёхбитная сетка на явно заданных подложках

Изменить сетку alpha наклейки, сохранив RGB и отверстие

После каталога показана исходная наклейка на тёмном, alpha4 на тёмном и тот же результат на светлом. Промежуточная прозрачность стала ступенчатой, RGB сохранены, alpha0 и 65535 остаются концами диапазона. alpha-only16.png хранит RGBA16; alpha-raw-preview8.png — отдельный RGBA8 просмотр, не непрозрачный фон.

Изменить сетку alpha наклейки, сохранив RGB и отверстиеПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$alpha = clone $product;
if (!$alpha->setImageChannelDepth(Imagick::CHANNEL_ALPHA, 4)) { throw new RuntimeException('Alpha depth failed'); }
$storage = clone $alpha;
$storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'alpha-only16.png', 16, true);
saveDepthPNG($loaded, 'alpha-raw-preview8.png', 8, true);
$originalDark = depthPreview($product, '#243c4d');
$alphaDark = depthPreview($loaded, '#243c4d');
$alphaLight = depthPreview($loaded, '#e6edf1');
$a = saveDepthPNG($originalDark, 'product-dark-preview8.png', 8);
$b = saveDepthPNG($alphaDark, 'alpha-dark-preview8.png', 8);
$c = saveDepthPNG($alphaLight, 'alpha-light-preview8.png', 8);
saveDepthComparison([$sourceView, $a, $b, $c], 'depth-alpha.png');
echo "depth-alpha.png\nalpha-only16.png\n";
printf("alpha-live=%d storage-read=%d\n", $alpha->getImageDepth(), $loaded->getImageDepth());

После каталога показана исходная наклейка на тёмном, alpha4 на тёмном и тот же результат на светлом. Промежуточная прозрачность стала ступенчатой, RGB сохранены, alpha0 и 65535 остаются концами диапазона. alpha-only16.png хранит RGBA16; alpha-raw-preview8.png — отдельный RGBA8 просмотр, не непрозрачный фон. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-alpha.png
alpha-only16.png
alpha-live=4 storage-read=16

Проверять реальные значения и не обещать восстановление

Ошибка ожиданияПроверка и граница
Getter16 значит 65536 реально занятых уровнейНет: это поле. После расширения 8→16 остаётся прежняя сетка. Число разных значений считается отдельно.
Depth4 создаёт 4 битный truecolorPNGRGB/RGBA PNG здесь 8/16. Мы отдельно указываем контейнер и сетку отсчётов.
RED4 затронул остальные каналы после сохраненияОбщее поле 4 может повлиять на кодирование. Перед PNG16 явно готовим отдельную storage-копию вызовом setImageDepth(16) и проверяем G/B по 16 битным отсчётам.
Градиент стал полосатымУменьшение точность склеивает значения. Увеличение поля не обращает эту потерю. Дизеринг — другой механизм и в этих программах не включён.
Изменение alpha похоже на размытиеЭто покомпонентное огрубление значений alpha, не пространственное размытие края и не автоматическое вырезание фона.
Изображение пустоеВсе три метода дали ImagickException в проверенной версии. Нужен загруженный растр; неверный PHP-тип может дать TypeError.
8 битный просмотр совпалОн не показывает все 16 битные различия. Точные файлы проверяются по сохранённым значениям, а не по их восьмибитной визуализации.

Собственный RGB16-вход содержит 352 разных значения в строке градиента; это реальная 16 битная подготовка, а не простое увеличение поля старой 8 битной картинки. Наклейка содержит известный alpha-градиент и отверстие ручки. Это учебная плоская графика, не цветопроба и не обещание совместимости с любым редактором/печатным процессом.

Полный переносимый helper
<?php
declare(strict_types=1);
function loadDepthInputs(): array {
    $hashes = ['source' => '9089b07729698243ee4d804ce374178e3cd8200d03f6bc6bec36e8f1dd49ac1a', 'product' => '367ad063613fe23c8aa9d6da88fbe1b59a10783a8fdb1f6140ba9424f53a9437'];
    $images = [];
    foreach ($hashes as $name => $hash) {
        $text = file_get_contents(__DIR__ . '/' . $name . '.png.b64');
        if ($text === false) { throw new RuntimeException('Cannot read ' . $name); }
        $bytes = base64_decode($text, true);
        if ($bytes === false || hash('sha256', $bytes) !== $hash) { throw new RuntimeException('Unexpected input ' . $name); }
        if (file_put_contents(__DIR__ . '/' . $name . '.png', $bytes) === false) { throw new RuntimeException('Cannot restore ' . $name); }
        $images[$name] = new Imagick(__DIR__ . '/' . $name . '.png');
    }
    return [$images['source'], $images['product']];
}
function saveDepthPNG(Imagick $image, string $filename, int $storageBits, bool $alpha=false): Imagick {
    if (!in_array($storageBits, [8, 16], true)) { throw new RuntimeException('PNG storage bits must be8 or16'); }
    $copy = clone $image; $copy->setImageFormat('png');
    $copy->setOption('png:bit-depth', (string)$storageBits);
    $copy->setOption('png:color-type', $alpha ? '6' : '2');
    if (!$copy->writeImage(__DIR__ . '/' . $filename)) { throw new RuntimeException('Cannot save ' . $filename); }
    return new Imagick(__DIR__ . '/' . $filename);
}
function depthPreview(Imagick $image, string $background): Imagick {
    $view = new Imagick(); $view->newImage($image->getImageWidth(), $image->getImageHeight(), $background);
    $view->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0);
    return $view;
}
function saveDepthComparison(array $panels, string $filename): void {
    $width = 0; $height = 0;
    foreach ($panels as $panel) { $width += $panel->getImageWidth(); $height = max($height, $panel->getImageHeight()); }
    $board = new Imagick(); $board->newImage($width, $height, 'white'); $x = 0;
    foreach ($panels as $panel) { $board->compositeImage($panel, Imagick::COMPOSITE_OVER, $x, 0); $x += $panel->getImageWidth(); }
    saveDepthPNG($board, $filename, 8);
}
Прочитанная проблемаНаш ответ
SO 34220981TIFF после сборки имеет другую заявленную глубину. Это мотивирует отдельно проверять объект и реальный заголовок записанного файла; наш пакет показывает PNG, а не реализует решение всего TIFF-конвейера.
SO 37351729Переход 8→16 не изменил привычные RGB-числа. Различаем шкалу представления, общее поле depth и новые фактические оттенки: увеличение поля не создаёт утраченную информацию.
SO 28769749RGBA16 путают с общей суммой бит пикселя. Поясняем 16 бит на каждую из четырёх компонент, отдельную alpha и реальные IHDR/sample данные PNG; не называем это 16 битами на весь RGBA-пиксель.
SO 27459174После растяжения ограниченного набора серых уровней появляются пропуски. Увеличение depth само их не заполняет; храните точный мастер и отдельно выбирайте тоновое преобразование/дизеринг.
SO 6350813Прозрачный серый PNG ведёт себя иначе в FFmpeg. Наш ответ ограничен различием контейнера, цветов и alpha и проверкой собственных PNG; исправление совместимости FFmpeg в уроке не заявляется.
SO 76162826В вопросе 2023 года 4BPP палитры с 16 цветами путают с depth4 каждой компоненты и дизерингом. Наше огрубление не гарантирует 16 цветную палитру или результат другого редактора; для палитры нужен отдельный маршрут.

Выбрать точность под задачу и продолжить

Все каналы → setImageDepth; выбранный канал → setImageChannelDepth; общее поле → getImageDepth
Все каналы → setImageDepth; выбранный канал → setImageChannelDepth; общее поле → getImageDepth

Упражнение: огрубить только синий канал до 4 бит, сохранив R/G и SKU. Решение: работать с выбранной областью рисунка, использовать CHANNEL_BLUE, затем явно подготовить storage-копию к 16 битному PNG и сравнить остальные компоненты/внешние пиксели с мастером. Это самостоятельное изменение; свидетельства главы относятся к исходным восьми программам.

Далее: формат, сжатие и quality, alpha и выбранная подложка, свои преобразования компонентов. Другие методы, исторические aliases и форматы остаются узлами полного справочника.

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

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

Imagick::setImageDepthЗадаёт общее поле depth и при уменьшении ниже Quantum-depth огрубляет обновляемые компоненты.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageDepth(int $depth): bool

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$copy = clone $image;
$ok = $copy->setImageDepth(4);

В проверенной Q16-сборке это огрубляет разрешённые к изменению каналы. Возвращённое true — статус, а не новое изображение.4 означает максимум 16 уровней на компоненту, не 16 цветов RGB: комбинаций может быть больше. Для градиента это намеренный контрпример со ступеньками.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Официальный контракт и границы реализации

Imagick::setImageDepth(int $depth): bool
ПараметрСмысл
$depthОбязательный int, число бит точности компоненты. Здесь 4/8/16. Это не размер картинки, число цветов всей картинки или качество JPEG.

Sets the image depth. Доступность: PECL imagick 2, PECL imagick 3. Возврат: Returns true on success. Официальных примеров и таблиц изменений у этих трёх XML-записей нет; полный XML сохранён ниже.

Проверенная версия: Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI. В ней getImageDepth читает поле текущего изображения, хотя внутренняя библиотека имеет и отдельную функцию анализа значений. Это разные пути. Все три PHP-метода требуют непустое изображение и в проверке дали ImagickException на пустом объекте; раздел ошибок getter в исходном XML не заполнен, уточнение относится к этой реализации.

При d=4 либо 8 и обычных неотрицательных Q16-значениях здесь n=floor(c×(2^d−1)/65535), затем c′=n×65535/(2^d−1). d — переданное число depth, n — целый номер уровня, c — исходная компонента; c′ — результат; floor означает округление вниз, например floor(2.9)=2. ^ в математической записи означает степень, не PHP-оператор XOR. Эта формула ограничена проверенной сборкой без HDRI и веткой без отдельно включённого дизеринга FloydSteinberg (распределения ошибки по соседним пикселям); другую глубину сборки или дизеринг нельзя молча считать тем же механизмом.

При depth≥16 в этой Q16-сборке метод только меняет поле depth. В пробе 32 было принято без новых значений; это не гарантия 32 битной внутренней точности или 32 битного truecolorPNG. Снижение точности теряет промежуточные значения; увеличение обратно их не вычисляет. RGB/RGBA PNG поддерживает 8- и 16 битные компоненты, поэтому 4 битная сетка здесь сохраняется в 8- или 16 битном контейнере.

Setters возвращают true при успехе, а внутренний отказ преобразуется PHP-обёрткой в ImagickException; неверный PHP-тип может дать TypeError. Реализация не обещает за приложение ограничить depth только 4/8/16 или проверить белый список каналов. Наши примеры используют известные положительные значения; внешние параметры надо отдельно ограничить разумным диапазоном и доступными константами. Отрицательные значения и бесконтрольные глубины не являются способом исследования возможного диапазона.

Весь официальный XML
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagedepth">
 <refnamediv>
  <refname>Imagick::setImageDepth</refname>
  <refpurpose>Sets the image depth</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageDepth</methodname>
   <methodparam><type>int</type><parameter>depth</parameter></methodparam>
  </methodsynopsis>
  <para>
   Sets the image depth.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>depth</parameter></term>
     <listitem>
      <para>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Огрубить все цветовые компоненты до четырёхбитной сетки

У текущего изображения depth=4, цвета выбраны из сетки максимум 16 уровней каждой компоненты. Для точного исследования сохранён PNG16; после чтения его getter возвращает 16. Это различие между сеткой значений, общим полем depth и числом бит хранения.

Огрубить все цветовые компоненты до четырёхбитной сеткиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$coarse = clone $source;
if (!$coarse->setImageDepth(4)) { throw new RuntimeException('Depth4 failed'); }
$storage = clone $coarse; $storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'all-four-storage16.png', 16);
$view = saveDepthPNG($loaded, 'all-four-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-all.png');
echo "depth-all.png\nall-four-storage16.png\n";
printf("live=%d stored-read=%d\n", $coarse->getImageDepth(), $loaded->getImageDepth());

У текущего изображения depth=4, цвета выбраны из сетки максимум 16 уровней каждой компоненты. Для точного исследования сохранён PNG16; после чтения его getter возвращает 16. Это различие между сеткой значений, общим полем depth и числом бит хранения. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-all.png
all-four-storage16.png
live=4 stored-read=16

Применить грубую сетку только к рисунку, сохранив SKU

Меняем только рисунок 352×132 от(24,88), затем вставляем обратно. Вне прямоугольника исходные 16 битные значения, градиенты и SKU сохранены точно. Это намеренная стилизация; уменьшение точности не является повышением качества или автоматическим способом улучшить текст.

Применить грубую сетку только к рисунку, сохранив SKUПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$region = $source->getImageRegion(352, 132, 24, 88);
$region->setImagePage(0, 0, 0, 0);
if (!$region->setImageDepth(4)) { throw new RuntimeException('Region depth failed'); }
$protected = clone $source;
$protected->compositeImage($region, Imagick::COMPOSITE_OVER, 24, 88);
$loaded = saveDepthPNG($protected, 'protected16.png', 16);
$view = saveDepthPNG($loaded, 'protected-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-protected.png');
echo "depth-protected.png\nprotected16.png\n";

Меняем только рисунок 352×132 от(24,88), затем вставляем обратно. Вне прямоугольника исходные 16 битные значения, градиенты и SKU сохранены точно. Это намеренная стилизация; уменьшение точности не является повышением качества или автоматическим способом улучшить текст. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-protected.png
protected16.png
Imagick::getImageDepthЧитает int общего поля depth текущего изображения; не пересчитывает количество разных значений.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageDepth(): int

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$depth = $image->getImageDepth();
echo $depth;

Getter — метод чтения. Он возвращает целое поле depth: например 16 у исходного PNG16,4 после уменьшения. Это не подсчёт разных цветов и не обещание, что произвольный PNG16 содержит все 65536 уровней. После сохранения и чтения 16 битного контейнера значение может стать 16 даже при грубой сетке.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Официальный контракт и границы реализации

Imagick::getImageDepth(): int
ПараметрСмысл
Нет аргументовПустые скобки(). Результат относится к текущему объекту/изображению, не доказывает 16 битную исходную информацию и может измениться после PNG-записи/чтения.

Gets the image depth. Доступность: PECL imagick 2, PECL imagick 3. Возврат: The image depth. Официальных примеров и таблиц изменений у этих трёх XML-записей нет; полный XML сохранён ниже.

Проверенная версия: Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI. В ней getImageDepth читает поле текущего изображения, хотя внутренняя библиотека имеет и отдельную функцию анализа значений. Это разные пути. Все три PHP-метода требуют непустое изображение и в проверке дали ImagickException на пустом объекте; раздел ошибок getter в исходном XML не заполнен, уточнение относится к этой реализации.

При d=4 либо 8 и обычных неотрицательных Q16-значениях здесь n=floor(c×(2^d−1)/65535), затем c′=n×65535/(2^d−1). d — переданное число depth, n — целый номер уровня, c — исходная компонента; c′ — результат; floor означает округление вниз, например floor(2.9)=2. ^ в математической записи означает степень, не PHP-оператор XOR. Эта формула ограничена проверенной сборкой без HDRI и веткой без отдельно включённого дизеринга FloydSteinberg (распределения ошибки по соседним пикселям); другую глубину сборки или дизеринг нельзя молча считать тем же механизмом.

После RED4 getter также сообщает 4, хотя G/B не снижались. После сохранения грубых значений в PNG16 и чтения он сообщает 16. Чтобы доказать точность, нужны известный источник и сравнение самих отсчётов; одного getter недостаточно. Число используемых уровней и глубина файла также не равны размеру файла в байтах.

Setters возвращают true при успехе, а внутренний отказ преобразуется PHP-обёрткой в ImagickException; неверный PHP-тип может дать TypeError. Реализация не обещает за приложение ограничить depth только 4/8/16 или проверить белый список каналов. Наши примеры используют известные положительные значения; внешние параметры надо отдельно ограничить разумным диапазоном и доступными константами. Отрицательные значения и бесконтрольные глубины не являются способом исследования возможного диапазона.

Весь официальный XML
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagedepth">
 <refnamediv>
  <refname>Imagick::getImageDepth</refname>
  <refpurpose>Gets the image depth</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>int</type><methodname>Imagick::getImageDepth</methodname>
   <void/>
  </methodsynopsis>
  <para>
   Gets the image depth.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  &no.function.parameters;
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   The image depth.
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Прочитать depth объекта и заново открытого PNG16

Вживую getter вернул 4, после хранения PNG16 и чтения вернул 16, хотя числовые значения остались на четырёхбитной сетке. Метод читает общее поле текущего изображения, не подсчитывает использованные уровни и не доказывает происхождение точных оттенков.

Прочитать depth объекта и заново открытого PNG16Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$coarse = clone $source; $coarse->setImageDepth(4);
$live = $coarse->getImageDepth();
$storage = clone $coarse; $storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'read-container16.png', 16);
$read = $loaded->getImageDepth();
$view = saveDepthPNG($loaded, 'read-container-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-read.png');
echo "depth-read.png\nread-container16.png\n";
printf("live=%d read=%d\n", $live, $read);

Вживую getter вернул 4, после хранения PNG16 и чтения вернул 16, хотя числовые значения остались на четырёхбитной сетке. Метод читает общее поле текущего изображения, не подсчитывает использованные уровни и не доказывает происхождение точных оттенков. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-read.png
read-container16.png
live=4 read=16

Обнаружить ложное восстановление точности в маршруте 16→8→16

Три просмотра: исходник, сохранённая 8 битная копия и 16 битный контейнер после увеличения поля. Отчёт снова показывает 16, но сохранённые значения последнего файла равны восьмибитной копии, а не исходнику. Поэтому при работе с градиентами важно сохранять точный мастер, а не полагаться на одно число getter.

Обнаружить ложное восстановление точности в маршруте 16→8→16Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$eight = clone $source; $eight->setImageDepth(8);
$expanded = clone $eight; $expanded->setImageDepth(16);
$readEight = saveDepthPNG($eight, 'route-eight.png', 8);
$readExpanded = saveDepthPNG($expanded, 'route-expanded16.png', 16);
$eightView = saveDepthPNG($readEight, 'route-eight-preview8.png', 8);
$expandedView = saveDepthPNG($readExpanded, 'route-expanded-preview8.png', 8);
saveDepthComparison([$sourceView, $eightView, $expandedView], 'depth-no-restore.png');
echo "depth-no-restore.png\nroute-eight.png\nroute-expanded16.png\n";
printf("source=%d eight=%d expanded=%d\n", $source->getImageDepth(), $eight->getImageDepth(), $expanded->getImageDepth());

Три просмотра: исходник, сохранённая 8 битная копия и 16 битный контейнер после увеличения поля. Отчёт снова показывает 16, но сохранённые значения последнего файла равны восьмибитной копии, а не исходнику. Поэтому при работе с градиентами важно сохранять точный мастер, а не полагаться на одно число getter. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-no-restore.png
route-eight.png
route-expanded16.png
source=16 eight=8 expanded=16
Imagick::setImageChannelDepthПрименяет уменьшение точности к выбранным каналам и меняет общее поле depth.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageChannelDepth(int $channel, int $depth): bool

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

$image — загруженное изображение. $ обозначает переменную; = присваивает; -> вызывает метод; () содержит аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе. RGB — красная, зелёная и синяя компоненты; RGBA добавляет alpha, где 0 прозрачен,1 непрозрачен. clone создаёт рабочую копию. Q16 здесь означает внутренние 16 битные целые значения компоненты от 0 до 65535; это отдельно от глубины хранения PNG.

$copy = clone $image;
$ok = $copy->setImageChannelDepth(Imagick::CHANNEL_RED, 4);

Первый аргумент выбирает красный канал, второй задаёт 4 битную сетку. Для alpha замените константу на CHANNEL_ALPHA. Остальные каналы в наших контролях сохранены. Общее поле depth при этом всё равно стало 4; для сохранения остальных 16 битных отсчётов перед PNG16 нужно явно подготовить отдельную копию:

$storage = clone $copy;
$storage->setImageDepth(16);

На Q16 этот второй вызов меняет поле хранения, не возвращает потерянные красные значения и не меняет оставшиеся 16 битные G/B. Оригинальный $copy продолжает сообщать 4. Следующая запись helper выбирает контейнер PNG16 отдельно.

if проверяет условие, ! отрицает статус; throw new RuntimeException прекращает цепочку при отказе. echo выводит текст, "\n" переводит строку, printf подставляет %d как целое. new Imagick(путь) заново читает файл. Основы: объекты и методы, массивы, файлы, исключения.

Официальный контракт и границы реализации

Imagick::setImageChannelDepth(int $channel, int $depth): bool
ПараметрСмысл
$channelОбязательный int-код CHANNEL_*. CHANNEL_RED — красная компонента, CHANNEL_ALPHA — прозрачность. В проверенной IM7-сборке коды 1 и 16, но в коде используем имена.
$depthОбязательный int, число бит выбранной сетки значений.4 даёт максимум 16 возможных уровней компоненты; наличие всех 16 в каждом изображении не гарантируется.

Sets the depth of a particular image channel. Доступность: PECL imagick 2, PECL imagick 3. Возврат: Returns true on success. Официальных примеров и таблиц изменений у этих трёх XML-записей нет; полный XML сохранён ниже.

Проверенная версия: Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI. В ней getImageDepth читает поле текущего изображения, хотя внутренняя библиотека имеет и отдельную функцию анализа значений. Это разные пути. Все три PHP-метода требуют непустое изображение и в проверке дали ImagickException на пустом объекте; раздел ошибок getter в исходном XML не заполнен, уточнение относится к этой реализации.

При d=4 либо 8 и обычных неотрицательных Q16-значениях здесь n=floor(c×(2^d−1)/65535), затем c′=n×65535/(2^d−1). d — переданное число depth, n — целый номер уровня, c — исходная компонента; c′ — результат; floor означает округление вниз, например floor(2.9)=2. ^ в математической записи означает степень, не PHP-оператор XOR. Эта формула ограничена проверенной сборкой без HDRI и веткой без отдельно включённого дизеринга FloydSteinberg (распределения ошибки по соседним пикселям); другую глубину сборки или дизеринг нельзя молча считать тем же механизмом.

В IM7 PHP-совместимость временно выбирает маску каналов и возвращает её после вызова. При успехе общее поле image depth всё равно меняется. Для RED4 оставшиеся G/B могут иметь 16 битные значения, поэтому перед PNG16 в программе явно вызывается setImageDepth(16) у отдельной storage-копии. Одного позднего настройки записи PNG недостаточно считать доказательством сохранения этих значений.

Setters возвращают true при успехе, а внутренний отказ преобразуется PHP-обёрткой в ImagickException; неверный PHP-тип может дать TypeError. Реализация не обещает за приложение ограничить depth только 4/8/16 или проверить белый список каналов. Наши примеры используют известные положительные значения; внешние параметры надо отдельно ограничить разумным диапазоном и доступными константами. Отрицательные значения и бесконтрольные глубины не являются способом исследования возможного диапазона.

Весь официальный XML
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagechanneldepth">
 <refnamediv>
  <refname>Imagick::setImageChannelDepth</refname>
  <refpurpose>Sets the depth of a particular image channel</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageChannelDepth</methodname>
   <methodparam><type>int</type><parameter>channel</parameter></methodparam>
   <methodparam><type>int</type><parameter>depth</parameter></methodparam>
  </methodsynopsis>
  <para>
   Sets the depth of a particular image channel.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>channel</parameter></term>
     <listitem>
      <para>
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>depth</parameter></term>
     <listitem>
      <para>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Огрубить только красный канал и сохранить остальные значения

CHANNEL_RED выбирает только красную компоненту. G/B остаются исходными 16 битными значениями; результат сохраняется с явной подготовкой копии к PNG16. Установка канала всё равно меняет общее поле depth на 4, поэтому это поле не является отчётом о глубине каждого канала.

Огрубить только красный канал и сохранить остальные значенияПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$red = clone $source;
if (!$red->setImageChannelDepth(Imagick::CHANNEL_RED, 4)) { throw new RuntimeException('Red depth failed'); }
$live = $red->getImageDepth();
$storage = clone $red;
$storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'red-only16.png', 16);
$view = saveDepthPNG($loaded, 'red-only-preview8.png', 8);
saveDepthComparison([$sourceView, $view], 'depth-red.png');
echo "depth-red.png\nred-only16.png\n";
printf("red-live=%d storage-read=%d\n", $live, $loaded->getImageDepth());

CHANNEL_RED выбирает только красную компоненту. G/B остаются исходными 16 битными значениями; результат сохраняется с явной подготовкой копии к PNG16. Установка канала всё равно меняет общее поле depth на 4, поэтому это поле не является отчётом о глубине каждого канала. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-red.png
red-only16.png
red-live=4 storage-read=16

Изменить сетку alpha наклейки, сохранив RGB и отверстие

После каталога показана исходная наклейка на тёмном, alpha4 на тёмном и тот же результат на светлом. Промежуточная прозрачность стала ступенчатой, RGB сохранены, alpha0 и 65535 остаются концами диапазона. alpha-only16.png хранит RGBA16; alpha-raw-preview8.png — отдельный RGBA8 просмотр, не непрозрачный фон.

Изменить сетку alpha наклейки, сохранив RGB и отверстиеПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/depth-fixture.php';
[$source, $product] = loadDepthInputs();
$sourceView = saveDepthPNG($source, 'source-preview8.png', 8);
$alpha = clone $product;
if (!$alpha->setImageChannelDepth(Imagick::CHANNEL_ALPHA, 4)) { throw new RuntimeException('Alpha depth failed'); }
$storage = clone $alpha;
$storage->setImageDepth(16);
$loaded = saveDepthPNG($storage, 'alpha-only16.png', 16, true);
saveDepthPNG($loaded, 'alpha-raw-preview8.png', 8, true);
$originalDark = depthPreview($product, '#243c4d');
$alphaDark = depthPreview($loaded, '#243c4d');
$alphaLight = depthPreview($loaded, '#e6edf1');
$a = saveDepthPNG($originalDark, 'product-dark-preview8.png', 8);
$b = saveDepthPNG($alphaDark, 'alpha-dark-preview8.png', 8);
$c = saveDepthPNG($alphaLight, 'alpha-light-preview8.png', 8);
saveDepthComparison([$sourceView, $a, $b, $c], 'depth-alpha.png');
echo "depth-alpha.png\nalpha-only16.png\n";
printf("alpha-live=%d storage-read=%d\n", $alpha->getImageDepth(), $loaded->getImageDepth());

После каталога показана исходная наклейка на тёмном, alpha4 на тёмном и тот же результат на светлом. Промежуточная прозрачность стала ступенчатой, RGB сохранены, alpha0 и 65535 остаются концами диапазона. alpha-only16.png хранит RGBA16; alpha-raw-preview8.png — отдельный RGBA8 просмотр, не непрозрачный фон. В одной папке нужны example.php, depth-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick. Выходы создаются программой. Полный helper открыт ниже; он выбирает тип хранения PNG и не вызывает три изучаемых метода.

Ожидаемый вывод
depth-alpha.png
alpha-only16.png
alpha-live=4 storage-read=16
Источники и обсуждения

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

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

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

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