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

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

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

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

Глава 366 · После файлов, объектов и изображений

Imagick: файл каталога, сжатие и поле качества

Сохранить реальный JPEG, проверить потери и байты, получить точный TIFF-мастер и RGBA PNG без смешения формата и настройки.

Получить отдельный файл и посмотреть записанный результат

Нужна самостоятельная картинка каталога для скачивания: сохранить размер 400×320, уменьшить передачу байтов и проверить, что стало с градиентом и мелким SKU. Сделаем JPEG-копию из собственного исходника, заново откроем именно записанный файл и покажем его пиксели. Исходник останется для следующих версий; JPEG-копию не выдаём за точный мастер.

Надписи RGB и нижняя строка «Вход 400×320: Q16 внутри, PNG8 на диске» — часть исходного учебного рисунка. Они не переписываются при JPEG/TIFF и не сообщают формат нового файла. Q16 в этой надписи — внутренний 16-битный диапазон компоненты в проверенной сборке, отдельно от восьмибитной записи PNG. PNG8 здесь означает 8 бит на компоненту RGB, а не индексированный PNG; фактический выход определяется записанными байтами и повторным чтением.

Точный собственный RGB-исходник 400×320 с градиентами, плашками и SKU
Точный собственный RGB-исходник 400×320 с градиентами, плашками и SKU
Только первый код: catalogue-web.jpg и его фактические декодированные пиксели
Только первый код: catalogue-web.jpg и его фактические декодированные пиксели
Понятие до схемыЗначение здесь
RGB / RGBARGB — красная, зелёная и синяя компоненты. RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Исходник каталога RGB, дополнительная собственная наклейка RGBA с известным отверстием ручки.
Растр и файлW — ширина, H — высота в пикселях; здесь W=400, H=320. Растр — 400×320 значений пикселей. Файл — закодированные байты. Разные файлы могут давать одинаковые пиксели; одинаковые размеры не доказывают одинаковое качество.
Формат, кодек и способ сжатияКодек — часть библиотеки, которая кодирует и декодирует выбранный формат. JPEG/PNG/TIFF определяют устройство файла; COMPRESSION_* — настройка алгоритма, которую конкретный кодек может использовать. Формат задаётся явно setImageFormat; writeImage создаёт байты.
Потери JPEGJPEG огрубляет коэффициенты преобразования изображения: это называют квантованием. После обратного декодирования часть значений пикселей отличается от исходных. Это не подсчёт процента оставшихся деталей.
Qualityq — целое поле настройки. Для наших JPEG 25/85/95 дают разные потери, 0 включает значение по умолчанию. Это не процент деталей. Getter читает поле или оценку декодера, а не оценивает полезность изображения.
Точный просмотрJPEG/TIFF сначала открывает Imagick; затем его декодированные пиксели сохраняются в PNG. Это избавляет иллюстрацию от дополнительного JPEG-сжатия. Составная картинка нужна для сравнения, самостоятельный JPEG остаётся отдельным файлом.
БайтыB означает байт, KiB — 1024 байта. Размер относится к настоящему JPEG/TIFF-файлу, а не к отдельному PNG просмотра.
Статусы и объектыДва метода установки (setters) возвращают bool true при успехе и меняют настройку текущего объекта. Метод чтения (getter) возвращает int. new Imagick(путь) создаёт объект из файла. Ни один из этих трёх методов сам не записывает файл.

Напечатанные RGB-числа и надписи на исходном рисунке остаются частью рисунка после JPEG, а не новыми измерениями пикселей. Старое сокращение «PNG8» в самом изображении означает наш RGB PNG с 8 битами на компоненту, color-type 2; файл не индексированный.

Настройка объекта → явный кодек и запись → файл → декодированные пиксели и отдельный отчёт
Настройка объекта → явный кодек и запись → файл → декодированные пиксели и отдельный отчёт

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$ok = $image->setImageCompression(Imagick::COMPRESSION_LZW);

Одна эта инструкция не создаёт TIFF. Для показанного TIFF-пути дополнительно нужны явный формат и разрешение использовать настройку текущего изображения:

$image->setImageFormat('tiff');
$image->setOption('tiff:preserve-compression', 'true');
$image->setImageCompression(Imagick::COMPRESSION_LZW);
$image->writeImage(__DIR__ . '/master.tif');

setOption задаёт строковую настройку кодеку TIFF: здесь она разрешает брать способ сжатия из текущего изображения. Без неё в ограниченной проверке запрошенный LZW дал несжатый TIFF. Это проверенная особенность данного пути, а не требование всех форматов.

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

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$image->setImageFormat('jpeg');
$ok = $image->setImageCompressionQuality(85);
$image->writeImage(__DIR__ . '/web.jpg');

85 — параметр JPEG-кодирования в этом примере. setImageFormat выбирает формат; setImageCompressionQuality хранит число; writeImage выполняет кодирование и запись. __DIR__ — папка файла программы, . соединяет строки в путь. Смена настройки сама не меняет уже существующий JPEG на диске. PNG не становится JPEG от COMPRESSION_JPEG и не теряет alpha из-за числа 85.

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

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$quality = $image->getImageCompressionQuality();
echo $quality;

Читаем целое число без аргументов. Для текущего объекта после установки 85 это 85. После JPEG декодер оценивает число по его таблицам квантования; после нашего PNG возвращается 0 при точных пикселях. Для отчёта также нужен $image->getImageFormat(), а для размера файла — filesize(путь). Getter не выполняет эти проверки за нас.

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

Перед полной программой: <?php открывает PHP; declare(strict_types=1) включает строгие типы. require подключает compression-fixture.php из __DIR__. Квадратные скобки [$source, $product] принимают два изображения из loadCompressionInputs; helper восстанавливает оба PNG из Base64 и проверяет SHA. saveCompressionPNG сохраняет показанные пиксели без нового JPEG-кодирования; saveCompressionComparison размещает полные панели без изменения масштаба. setImageDepth(8) выбирает восьмибитную запись: наши исходные PNG уже имеют 8 бит на компоненту. Для другого входа изменение глубины может потерять точность, поэтому это не универсальное действие без изменения пикселей. Все исходники helper опубликованы ниже. Строка if (!$web->writeImage(...)) прекращает программу, если запись не удалась; исключения библиотеки также прерывают CLI-запуск с ошибкой.

Сохранить отдельную JPEG-копию каталога и посмотреть именно записанные пиксели

Слева точный исходник, справа JPEG после записи и повторного чтения Imagick. catalogue-web.jpg — самостоятельный файл для передачи; first-decoded.png показывает декодированные пиксели этого JPEG без нового сжатия JPEG. Размер растра остаётся 400×320. Измеренный размер файла и потери относятся к сохранённому результату, а не обещаются для любого каталога.

Сохранить отдельную JPEG-копию каталога и посмотреть именно записанные пикселиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$web = clone $source;
$web->setImageFormat('jpeg');
$web->setImageDepth(8);
if (!$web->setImageCompression(Imagick::COMPRESSION_JPEG)) { throw new RuntimeException('Compression setting failed'); }
if (!$web->setImageCompressionQuality(85)) { throw new RuntimeException('Quality setting failed'); }
if (!$web->writeImage(__DIR__ . '/catalogue-web.jpg')) { throw new RuntimeException('JPEG write failed'); }
$decoded = new Imagick(__DIR__ . '/catalogue-web.jpg');
saveCompressionPNG($decoded, 'first-decoded.png');
saveCompressionComparison([$source, $decoded], 'compression-first.png');
echo "compression-first.png\ncatalogue-web.jpg\nfirst-decoded.png\n";
printf("live-quality=%d read-quality=%d format=%s\n", $web->getImageCompressionQuality(), $decoded->getImageCompressionQuality(), $decoded->getImageFormat());

Слева точный исходник, справа JPEG после записи и повторного чтения Imagick. catalogue-web.jpg — самостоятельный файл для передачи; first-decoded.png показывает декодированные пиксели этого JPEG без нового сжатия JPEG. Размер растра остаётся 400×320. Измеренный размер файла и потери относятся к сохранённому результату, а не обещаются для любого каталога. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-first.png
catalogue-web.jpg
first-decoded.png
live-quality=85 read-quality=85 format=JPEG

Проверить, какое действие действительно изменило файл

Настройка и сохранение — два разных действия. Вторая панель ещё не проходила JPEG-кодирование, поэтому в ней нет JPEG-потерь. Две следующие панели проверяют именно путь текущего image quality к PNG, без обещаний об одинаковом поведении всех кодеков или настроек. setOption в этом контроле выбирает тип RGB PNG, а не изображает качество.

Отделить настройку объекта от кодирования и проверить PNG 10/90

Панели: исходник; объект после двух setters, ещё без кодирования; перечитанный PNG с quality 10; перечитанный PNG с quality 90. Пиксели всех четырёх совпадают. В проверенном пути эти два PNG имеют одинаковые байты: изменение image quality не стало регулятором PNG-сжатия. Getter после PNG вернул 0, хотя сохранены все исходные пиксели.

Отделить настройку объекта от кодирования и проверить PNG 10/90Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$configured = clone $source;
$configured->setImageCompression(Imagick::COMPRESSION_JPEG);
$configured->setImageCompressionQuality(85);
$low = clone $source; $low->setImageFormat('png'); $low->setImageDepth(8); $low->setOption('png:color-type', '2');
$low->setImageCompression(Imagick::COMPRESSION_ZIP); $low->setImageCompressionQuality(10);
if (!$low->writeImage(__DIR__ . '/control-q10.png')) { throw new RuntimeException('PNG write failed'); }
$high = clone $source; $high->setImageFormat('png'); $high->setImageDepth(8); $high->setOption('png:color-type', '2');
$high->setImageCompression(Imagick::COMPRESSION_ZIP); $high->setImageCompressionQuality(90);
if (!$high->writeImage(__DIR__ . '/control-q90.png')) { throw new RuntimeException('PNG write failed'); }
$readLow = new Imagick(__DIR__ . '/control-q10.png'); $readHigh = new Imagick(__DIR__ . '/control-q90.png');
saveCompressionComparison([$source, $configured, $readLow, $readHigh], 'compression-controls.png');
echo "compression-controls.png\ncontrol-q10.png\ncontrol-q90.png\n";
printf("configured=%d png10-read=%d png90-read=%d\n", $configured->getImageCompressionQuality(), $readLow->getImageCompressionQuality(), $readHigh->getImageCompressionQuality());

Панели: исходник; объект после двух setters, ещё без кодирования; перечитанный PNG с quality 10; перечитанный PNG с quality 90. Пиксели всех четырёх совпадают. В проверенном пути эти два PNG имеют одинаковые байты: изменение image quality не стало регулятором PNG-сжатия. Getter после PNG вернул 0, хотя сохранены все исходные пиксели. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-controls.png
control-q10.png
control-q90.png
configured=85 png10-read=0 png90-read=0

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

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$ok = $image->setImageCompression(Imagick::COMPRESSION_LZW);

Одна эта инструкция не создаёт TIFF. Для показанного TIFF-пути дополнительно нужны явный формат и разрешение использовать настройку текущего изображения:

$image->setImageFormat('tiff');
$image->setOption('tiff:preserve-compression', 'true');
$image->setImageCompression(Imagick::COMPRESSION_LZW);
$image->writeImage(__DIR__ . '/master.tif');

setOption задаёт строковую настройку кодеку TIFF: здесь она разрешает брать способ сжатия из текущего изображения. Без неё в ограниченной проверке запрошенный LZW дал несжатый TIFF. Это проверенная особенность данного пути, а не требование всех форматов.

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

TIFF без сжатия и LZW: разные байты при точных пикселях; отдельно мастер и веб-копия
TIFF без сжатия и LZW: разные байты при точных пикселях; отдельно мастер и веб-копия

Выбрать реально используемое сжатие TIFF: без сжатия и LZW

После исходника показаны два TIFF, заново прочитанные Imagick. COMPRESSION_NO и COMPRESSION_LZW в этом примере включены для TIFF явной опцией tiff:preserve-compression=true. Файлы имеют разные способы хранения и размеры; оба декодируются в точные исходные пиксели. Одинаковая картинка здесь и есть полезное свойство сжатия без потерь.

Выбрать реально используемое сжатие TIFF: без сжатия и LZWПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$plain = clone $source; $plain->setImageFormat('tiff'); $plain->setImageDepth(8);
$plain->setOption('tiff:preserve-compression', 'true');
if (!$plain->setImageCompression(Imagick::COMPRESSION_NO)) { throw new RuntimeException('No-compression setting failed'); }
if (!$plain->writeImage(__DIR__ . '/catalogue-plain.tif')) { throw new RuntimeException('TIFF write failed'); }
$packed = clone $source; $packed->setImageFormat('tiff'); $packed->setImageDepth(8);
$packed->setOption('tiff:preserve-compression', 'true');
if (!$packed->setImageCompression(Imagick::COMPRESSION_LZW)) { throw new RuntimeException('LZW setting failed'); }
if (!$packed->writeImage(__DIR__ . '/catalogue-lzw.tif')) { throw new RuntimeException('TIFF write failed'); }
$readPlain = new Imagick(__DIR__ . '/catalogue-plain.tif'); $readPacked = new Imagick(__DIR__ . '/catalogue-lzw.tif');
saveCompressionPNG($readPlain, 'plain-decoded.png'); saveCompressionPNG($readPacked, 'lzw-decoded.png');
saveCompressionComparison([$source, $readPlain, $readPacked], 'compression-tiff.png');
echo "compression-tiff.png\ncatalogue-plain.tif\ncatalogue-lzw.tif\nplain-decoded.png\nlzw-decoded.png\n";

После исходника показаны два TIFF, заново прочитанные Imagick. COMPRESSION_NO и COMPRESSION_LZW в этом примере включены для TIFF явной опцией tiff:preserve-compression=true. Файлы имеют разные способы хранения и размеры; оба декодируются в точные исходные пиксели. Одинаковая картинка здесь и есть полезное свойство сжатия без потерь. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-tiff.png
catalogue-plain.tif
catalogue-lzw.tif
plain-decoded.png
lzw-decoded.png

В реальном каталоге полезно разделить точный мастер и производную копию. Оба создаются из исходника, а не друг из друга после нескольких JPEG-пересохранений. В коде setOption разрешает TIFF использовать выбранное сжатие; отдельные setImageFormat и COMPRESSION_JPEG задают JPEG-ветвь. Исходные 400×320 и мелкий SKU в TIFF остаются точными.

Хранить точный мастер и отдельно сделать JPEG для каталога

Исходник → TIFF LZW как точная копия пикселей → самостоятельная JPEG-копия quality 85. Повторные веб-версии следует создавать из исходника или мастера, чтобы не накапливать повторное JPEG-сжатие. Мастер сохраняет и SKU точно; JPEG нужно отдельно оценить на тексте и градиенте.

Хранить точный мастер и отдельно сделать JPEG для каталогаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$master = clone $source; $master->setImageFormat('tiff'); $master->setImageDepth(8);
$master->setOption('tiff:preserve-compression', 'true');
$master->setImageCompression(Imagick::COMPRESSION_LZW);
if (!$master->writeImage(__DIR__ . '/master-lzw.tif')) { throw new RuntimeException('Master write failed'); }
$web = clone $source; $web->setImageFormat('jpeg'); $web->setImageDepth(8);
$web->setImageCompression(Imagick::COMPRESSION_JPEG); $web->setImageCompressionQuality(85);
if (!$web->writeImage(__DIR__ . '/web-copy.jpg')) { throw new RuntimeException('Web copy write failed'); }
$readMaster = new Imagick(__DIR__ . '/master-lzw.tif'); $readWeb = new Imagick(__DIR__ . '/web-copy.jpg');
saveCompressionPNG($readMaster, 'master-decoded.png'); saveCompressionPNG($readWeb, 'web-decoded.png');
saveCompressionComparison([$source, $readMaster, $readWeb], 'compression-master-web.png');
echo "compression-master-web.png\nmaster-lzw.tif\nweb-copy.jpg\nmaster-decoded.png\nweb-decoded.png\n";

Исходник → TIFF LZW как точная копия пикселей → самостоятельная JPEG-копия quality 85. Повторные веб-версии следует создавать из исходника или мастера, чтобы не накапливать повторное JPEG-сжатие. Мастер сохраняет и SKU точно; JPEG нужно отдельно оценить на тексте и градиенте. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-master-web.png
master-lzw.tif
web-copy.jpg
master-decoded.png
web-decoded.png

Сравнить потери JPEG и отдельно выбрать формат наклейки

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$image->setImageFormat('jpeg');
$ok = $image->setImageCompressionQuality(85);
$image->writeImage(__DIR__ . '/web.jpg');

85 — параметр JPEG-кодирования в этом примере. setImageFormat выбирает формат; setImageCompressionQuality хранит число; writeImage выполняет кодирование и запись. __DIR__ — папка файла программы, . соединяет строки в путь. Смена настройки сама не меняет уже существующий JPEG на диске. PNG не становится JPEG от COMPRESSION_JPEG и не теряет alpha из-за числа 85.

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

JPEG 25/95: реальные размеры файлов и одинаковые увеличенные области мелких деталей
JPEG 25/95: реальные размеры файлов и одинаковые увеличенные области мелких деталей

Сравнить JPEG 25 и 95 на градиенте и мелком тексте

Три полных панели: исходник, декодированный JPEG 25, декодированный JPEG 95. Для этого рисунка у 25 сильнее заметны потери и меньше файл; 95 лучше сохраняет пиксели, но это всё ещё JPEG с потерями. Число не обозначает процент оставшихся деталей, а разница размеров зависит от изображения и кодека.

Сравнить JPEG 25 и 95 на градиенте и мелком текстеПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$low = clone $source; $low->setImageFormat('jpeg'); $low->setImageDepth(8);
$low->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$low->setImageCompressionQuality(25)) { throw new RuntimeException('Quality setting failed'); }
if (!$low->writeImage(__DIR__ . '/quality-25.jpg')) { throw new RuntimeException('JPEG write failed'); }
$high = clone $source; $high->setImageFormat('jpeg'); $high->setImageDepth(8);
$high->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$high->setImageCompressionQuality(95)) { throw new RuntimeException('Quality setting failed'); }
if (!$high->writeImage(__DIR__ . '/quality-95.jpg')) { throw new RuntimeException('JPEG write failed'); }
$readLow = new Imagick(__DIR__ . '/quality-25.jpg'); $readHigh = new Imagick(__DIR__ . '/quality-95.jpg');
saveCompressionPNG($readLow, 'quality-25-decoded.png'); saveCompressionPNG($readHigh, 'quality-95-decoded.png');
saveCompressionComparison([$source, $readLow, $readHigh], 'compression-jpeg-quality.png');
echo "compression-jpeg-quality.png\nquality-25.jpg\nquality-95.jpg\nquality-25-decoded.png\nquality-95-decoded.png\n";

Три полных панели: исходник, декодированный JPEG 25, декодированный JPEG 95. Для этого рисунка у 25 сильнее заметны потери и меньше файл; 95 лучше сохраняет пиксели, но это всё ещё JPEG с потерями. Число не обозначает процент оставшихся деталей, а разница размеров зависит от изображения и кодека. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-jpeg-quality.png
quality-25.jpg
quality-95.jpg
quality-25-decoded.png
quality-95-decoded.png

Число quality не выбирает политику прозрачности. Вторая задача — PNG-наклейка с отверстиями и отдельная непрозрачная JPEG-версия. OVER — наложение слоя поверх непрозрачной подложки: непрозрачные части закрывают фон, прозрачные показывают его, промежуточная alpha смешивает цвета. compressionPreview открыто выполняет это наложение поверх выбранного фона; это не удаление фона и не восстановление отверстия из JPEG. Тёмная подложка в просмотре не записана в sticker-preserved.png: сам файл остаётся RGBA.

Один RGBA-вход: точная PNG-наклейка и явно выбранный белый фон JPEG
Один RGBA-вход: точная PNG-наклейка и явно выбранный белый фон JPEG

Доставить прозрачную PNG-наклейку и отдельно непрозрачный JPEG на белом

Панели: RGB-каталог как общий вход; наклейка на белом до JPEG; сохранённая RGBA PNG-наклейка поверх тёмной подложки; JPEG после явного наложения на белый и повторного чтения. В PNG сохранены alpha и отверстие ручки. JPEG хранит выбранный белый фон и не может затем раскрыть его как прозрачность. Одинаковое quality 85 не делает форматы одинаковыми.

Доставить прозрачную PNG-наклейку и отдельно непрозрачный JPEG на беломПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$sticker = clone $product; $sticker->setImageFormat('png'); $sticker->setImageDepth(8); $sticker->setOption('png:color-type', '6');
$sticker->setImageCompression(Imagick::COMPRESSION_ZIP); $sticker->setImageCompressionQuality(85);
if (!$sticker->writeImage(__DIR__ . '/sticker-preserved.png')) { throw new RuntimeException('Sticker write failed'); }
$white = compressionPreview($product, 'white');
$jpeg = clone $white; $jpeg->setImageFormat('jpeg'); $jpeg->setImageDepth(8);
$jpeg->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$jpeg->setImageCompressionQuality(85)) { throw new RuntimeException('Quality setting failed'); }
if (!$jpeg->writeImage(__DIR__ . '/sticker-white.jpg')) { throw new RuntimeException('Opaque JPEG write failed'); }
$readPNG = new Imagick(__DIR__ . '/sticker-preserved.png'); $readJPEG = new Imagick(__DIR__ . '/sticker-white.jpg');
saveCompressionPNG($readJPEG, 'sticker-jpeg-decoded.png');
$darkPreview = compressionPreview($readPNG, '#243c4d');
saveCompressionComparison([$source, $white, $darkPreview, $readJPEG], 'compression-alpha-format.png');
echo "compression-alpha-format.png\nsticker-preserved.png\nsticker-white.jpg\nsticker-jpeg-decoded.png\n";

Панели: RGB-каталог как общий вход; наклейка на белом до JPEG; сохранённая RGBA PNG-наклейка поверх тёмной подложки; JPEG после явного наложения на белый и повторного чтения. В PNG сохранены alpha и отверстие ручки. JPEG хранит выбранный белый фон и не может затем раскрыть его как прозрачность. Одинаковое quality 85 не делает форматы одинаковыми. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-alpha-format.png
sticker-preserved.png
sticker-white.jpg
sticker-jpeg-decoded.png

Прочитать настройку без выдуманной оценки изображения

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$quality = $image->getImageCompressionQuality();
echo $quality;

Читаем целое число без аргументов. Для текущего объекта после установки 85 это 85. После JPEG декодер оценивает число по его таблицам квантования; после нашего PNG возвращается 0 при точных пикселях. Для отчёта также нужен $image->getImageFormat(), а для размера файла — filesize(путь). Getter не выполняет эти проверки за нас.

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

Поле до записи, оценка JPEG и PNG с quality 0 при точных пикселях
Поле до записи, оценка JPEG и PNG с quality 0 при точных пикселях

Прочитать quality до записи и после JPEG с настройкой 0

В текущем объекте установили 0. В проверенном JPEG-кодеке это выбор значения по умолчанию, а не уничтожение качества: после чтения файла getter оценил 92 по таблицам квантования JPEG. Getter не сравнивает картинку с исходником и не обнаруживает потерянный текст.

Прочитать quality до записи и после JPEG с настройкой 0Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$web = clone $source; $web->setImageFormat('jpeg'); $web->setImageDepth(8);
$web->setImageCompression(Imagick::COMPRESSION_JPEG); $web->setImageCompressionQuality(0);
$liveQuality = $web->getImageCompressionQuality();
if (!$web->writeImage(__DIR__ . '/default-quality.jpg')) { throw new RuntimeException('JPEG write failed'); }
$loaded = new Imagick(__DIR__ . '/default-quality.jpg');
$readQuality = $loaded->getImageCompressionQuality();
saveCompressionPNG($loaded, 'default-decoded.png');
saveCompressionComparison([$source, $loaded], 'compression-get-default.png');
echo "compression-get-default.png\ndefault-quality.jpg\ndefault-decoded.png\n";
printf("live-quality=%d read-quality=%d\n", $liveQuality, $readQuality);

В текущем объекте установили 0. В проверенном JPEG-кодеке это выбор значения по умолчанию, а не уничтожение качества: после чтения файла getter оценил 92 по таблицам квантования JPEG. Getter не сравнивает картинку с исходником и не обнаруживает потерянный текст. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-get-default.png
default-quality.jpg
default-decoded.png
live-quality=0 read-quality=92

Для приёмки файла нельзя смешивать числовое поле и визуальную оценку. Во второй практике отчёт читает JPEG и PNG. PNG имеет 0 и сохранённую alpha; это не причина объявить файл плохим. Формат, размеры, наличие alpha, байты и читаемость проверяются отдельно. getImageAlphaChannel возвращает bool, а приведение (int) в последней строке превращает true/false в 1/0 для отчёта. В программах показывается известный вход; загрузка произвольных пользовательских файлов потребует ограничений размера/формата и безопасной политики обработки.

Составить отчёт о JPEG и PNG, не объявляя PNG с quality 0 испорченным

После исходника показаны прочитанный JPEG и PNG-наклейка на тёмном. Отчёт даёт JPEG 85, PNG 0 и активную alpha у PNG. Поэтому правило «отклонить любой файл при quality<80» неверно для этих двух форматов. Сначала читаем фактический формат; отдельно проверяем пиксели, размер файла, прозрачность и требования к доставке.

Составить отчёт о JPEG и PNG, не объявляя PNG с quality 0 испорченнымПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$jpeg = clone $source; $jpeg->setImageFormat('jpeg'); $jpeg->setImageDepth(8);
$jpeg->setImageCompression(Imagick::COMPRESSION_JPEG); $jpeg->setImageCompressionQuality(85);
if (!$jpeg->writeImage(__DIR__ . '/incoming-catalogue.jpg')) { throw new RuntimeException('JPEG write failed'); }
$png = clone $product; $png->setImageFormat('png'); $png->setImageDepth(8); $png->setOption('png:color-type', '6');
$png->setImageCompression(Imagick::COMPRESSION_ZIP); $png->setImageCompressionQuality(85);
if (!$png->writeImage(__DIR__ . '/incoming-sticker.png')) { throw new RuntimeException('PNG write failed'); }
$readJPEG = new Imagick(__DIR__ . '/incoming-catalogue.jpg'); $readPNG = new Imagick(__DIR__ . '/incoming-sticker.png');
$jpegQuality = $readJPEG->getImageCompressionQuality(); $pngQuality = $readPNG->getImageCompressionQuality();
saveCompressionPNG($readJPEG, 'incoming-jpeg-decoded.png');
$pngPreview = compressionPreview($readPNG, '#243c4d');
saveCompressionComparison([$source, $readJPEG, $pngPreview], 'compression-format-report.png');
echo "compression-format-report.png\nincoming-catalogue.jpg\nincoming-sticker.png\nincoming-jpeg-decoded.png\n";
printf("JPEG quality-field=%d; PNG quality-field=%d alpha=%d\n", $jpegQuality, $pngQuality, (int)$readPNG->getImageAlphaChannel());

После исходника показаны прочитанный JPEG и PNG-наклейка на тёмном. Отчёт даёт JPEG 85, PNG 0 и активную alpha у PNG. Поэтому правило «отклонить любой файл при quality<80» неверно для этих двух форматов. Сначала читаем фактический формат; отдельно проверяем пиксели, размер файла, прозрачность и требования к доставке. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-format-report.png
incoming-catalogue.jpg
incoming-sticker.png
incoming-jpeg-decoded.png
JPEG quality-field=85; PNG quality-field=0 alpha=1

Проверять байты, пиксели, alpha и отказы отдельно

Наблюдение или ошибкаЧто делать
После setter картинка прежняяОжидаемо: изменилось поле, а не пиксели. Запишите выбранный формат и заново прочитайте файл.
PNG 10/90 дал одинаковые байтыТак сработал проверенный путь текущего image quality. Не обещайте эффект без проверки конкретного кодека; PNG имеет собственные настройки, а не JPEG-процент потерь.
TIFF LZW без опции оказался несжатымВ наших примерах явно включено tiff:preserve-compression=true. Это объяснимое разрешение кодеку использовать image compression, а не скрытая подготовка.
quality 0 у JPEG и PNGДля JPEG-пробы до записи это default, после файла оценка 92; PNG вернул 0 при точных пикселях. Сначала учитывайте формат и историю чтения.
JPEG стал больше исходного PNGВозможно на плоской графике и тексте. Никакой setter не обещает уменьшить любой файл. Сравните реальные байты и выберите формат по содержимому.
Пропали прозрачные отверстияJPEG не сохраняет alpha. Нужна исходная RGBA PNG либо заранее выбранный непрозрачный фон; значение quality не возвращает прозрачность.
true, но нужного файла нетSetter не пишет файл. Проверяйте writeImage и исключения; расширение и HTTP-заголовок должны соответствовать настоящим байтам.
Разный просмотр JPEG в двух библиотекахНезависимые декодеры могут слегка различаться. Иллюстрации получены повторным чтением Imagick; не требуем точного равенства JPEG-пикселей другого декодера.

Измерения размеров файлов и ошибок относятся к сохранённым результатам этой сборки, а не являются постоянными значениями для всех систем. Точность TIFF/PNG проверена по декодированным пикселям; JPEG допускает потери, особенно вокруг текста и цветных границ. Встроенные подписи исходника не заменяют измерения после кодирования. Основной запуск: восемь самостоятельных программ, каждая со своими входными файлами и выводом; дополнительных скрытых целевых операций helper не выполняет.

Полный переносимый helper
<?php
declare(strict_types=1);
function loadCompressionInputs(): array {
    $hashes = ['source' => '453b22e19273f2fdd54ec6a7f0cd9e96a7b08c70cc4cc854838d1428fea207c6', 'product' => 'f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c'];
    $images = [];
    foreach ($hashes as $name => $hash) {
        $encoded = file_get_contents(__DIR__ . '/' . $name . '.png.b64');
        if ($encoded === false) { throw new RuntimeException('Cannot read ' . $name); }
        $bytes = base64_decode($encoded, true);
        if ($bytes === false || hash('sha256', $bytes) !== $hash) { throw new RuntimeException('Unexpected bytes for ' . $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 compressionPreview(Imagick $image, string $background): Imagick {
    $preview = new Imagick(); $preview->newImage($image->getImageWidth(), $image->getImageHeight(), $background);
    $preview->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0); return $preview;
}
function saveCompressionPNG(Imagick $image, string $filename, bool $withAlpha=false): void {
    $saved = clone $image; $saved->setImageFormat('png'); $saved->setImageDepth(8);
    $saved->setOption('png:color-type', $withAlpha ? '6' : '2');
    if (!$saved->writeImage(__DIR__ . '/' . $filename)) { throw new RuntimeException('Cannot save ' . $filename); }
}
function saveCompressionComparison(array $panels, string $filename): void {
    $width = 0; $height = 0;
    foreach ($panels as $panel) { $width += $panel->getImageWidth(); $height = max($height, $panel->getImageHeight()); }
    $canvas = new Imagick(); $canvas->newImage($width, $height, 'white'); $x = 0;
    foreach ($panels as $panel) { $canvas->compositeImage($panel, Imagick::COMPOSITE_OVER, $x, intdiv($height-$panel->getImageHeight(), 2)); $x += $panel->getImageWidth(); }
    saveCompressionPNG($canvas, $filename);
}
Прочитанная проблемаНаше решение
SO 26983819PNG для мобильного приложения не уменьшается от перебора quality/COMPRESSION. Наш ответ — проверить фактический путь настроек и сохранённый файл: в этом пути PNG 10/90 одинаковы; не обещаем универсальный JPEG-процент для PNG.
SO 46441364Два похожих имени setImageCompressionQuality и setCompressionQuality вызывают путаницу. Этот урок устанавливает поле текущего изображения и проверяет его использование при записи; другую настройку процесса записи не подменяем одним именем.
SO 22755833Запрошенный TIFF LZW становится больше. Наши TIFF явно разрешают использовать image compression, после чего проверяются настоящий tag NO/LZW, байты и точные декодированные пиксели. Совместимость с внешним PDF-получателем и устройство strips здесь не реализованы.
SO 36385392Цикл снижения качества не меняет размер ожидаемым образом. Мы ограниченно сравниваем реальные JPEG 25/95 и измеряем сохранённые файлы; автоматического подбора под лимит байтов в этих восьми программах нет.
SO 6610739Прозрачный PNG после JPEG получает нежелательный фон. Для самостоятельной наклейки оставляем точный RGBA PNG; для JPEG сначала явно накладываем на выбранный белый фон.
SO 79264175В вопросе 2024 года WebP с quality 0 оказался крупнее варианта 1. Это контекст ошибки «ноль означает минимум байтов», а не проверка WebP в этом уроке. Наша JPEG-проба отдельно показывает 0 как выбор значения по умолчанию; чужие выводы о WebP не переносим.

Выбрать формат под доставку и проверить свой компромисс

Нужен алгоритм → setImageCompression; параметр → setImageCompressionQuality; числовое поле → getImageCompressionQuality; запись всегда отдельно
Нужен алгоритм → setImageCompression; параметр → setImageCompressionQuality; числовое поле → getImageCompressionQuality; запись всегда отдельно

Упражнение: нужен меньший JPEG, но SKU должен оставаться читаемым. Создайте отдельную копию исходника с quality 70, сохраните в новый файл, перечитайте и сравните те же пиксели SKU и размер. Решение не состоит в объявлении 70 «достаточным»: пригодность подтверждает сравнение текста и требования проекта. Это самостоятельное продолжение; свидетельства главы относятся к исходным восьми запускам.

Следующий шаг: alpha и выбранный непрозрачный фон, самостоятельная вставка и поля, плотность и физический номинал без изменения пикселей. Исторические aliases и другие форматы остаются отдельными узлами полного справочника.

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

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

Imagick::setImageCompressionЗадаёт код способа сжатия текущему изображению; формат и запись файла задаются отдельно.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageCompression(int $compression): bool

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$ok = $image->setImageCompression(Imagick::COMPRESSION_LZW);

Одна эта инструкция не создаёт TIFF. Для показанного TIFF-пути дополнительно нужны явный формат и разрешение использовать настройку текущего изображения:

$image->setImageFormat('tiff');
$image->setOption('tiff:preserve-compression', 'true');
$image->setImageCompression(Imagick::COMPRESSION_LZW);
$image->writeImage(__DIR__ . '/master.tif');

setOption задаёт строковую настройку кодеку TIFF: здесь она разрешает брать способ сжатия из текущего изображения. Без неё в ограниченной проверке запрошенный LZW дал несжатый TIFF. Это проверенная особенность данного пути, а не требование всех форматов.

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

Полный контракт и границы версии

Imagick::setImageCompression(int $compression): bool
ПараметрСмысл
$compressionОбязательный int — именованная константа COMPRESSION_*. В примерах COMPRESSION_NO, COMPRESSION_LZW, COMPRESSION_JPEG и COMPRESSION_ZIP. Это не расширение файла, число качества или количество байтов.

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

В проверенной Imagick 3.8.1 / ImageMagick 7.1.1-46 метод присваивает поле сжатия текущего изображения. Поддержка конкретного алгоритма определяется форматом и сборкой. COMPRESSION_JPEG не выбирает JPEG вместо PNG, а COMPRESSION_ZIP не обещает ZIP-архив или уменьшение любого файла. В TIFF-примерах явно включено tiff:preserve-compression=true; сравниваются способы NO и LZW, оба без потери исходных RGB-пикселей.

Оба setters на пустом объекте в проверке выбросили ImagickException. PHP-обёртка преобразует отказ внутреннего setter в это исключение; неверный PHP-тип может дать TypeError. Реализация не проверяет диапазон качества 0…100 и разрешённый список кодов за приложение. Для внешнего JPEG quality разумно самим разрешить целые 1…100 либо явно поддержанный 0; для compression — известные именованные константы. Это политика приложения, а не обещание автоматической валидации метода. Ошибка writeImage или отсутствие нужного кодека — отдельный отказ записи, который также надо обработать.

Возвращённое true подтверждает установку настройки, но не запись файла, уменьшение байтов, читаемость SKU, сохранение alpha или поддержку алгоритма данным кодеком. JPEG допускает потери и не сохраняет прозрачность; перед JPEG в задаче наклейки явно выбран белый фон. Наша PNG-наклейка хранит RGBA, а видимые составные PNG — RGB с 8 битами на компоненту. Это не индексированный PNG и не доказательство готовности к печати.

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

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageCompression</methodname>
   <methodparam><type>int</type><parameter>compression</parameter></methodparam>
  </methodsynopsis>
  <para>
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>compression</parameter></term>
     <listitem>
      <para>
      One of the <constant>COMPRESSION</constant> constants
      </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
-->

Выбрать реально используемое сжатие TIFF: без сжатия и LZW

После исходника показаны два TIFF, заново прочитанные Imagick. COMPRESSION_NO и COMPRESSION_LZW в этом примере включены для TIFF явной опцией tiff:preserve-compression=true. Файлы имеют разные способы хранения и размеры; оба декодируются в точные исходные пиксели. Одинаковая картинка здесь и есть полезное свойство сжатия без потерь.

Выбрать реально используемое сжатие TIFF: без сжатия и LZWПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$plain = clone $source; $plain->setImageFormat('tiff'); $plain->setImageDepth(8);
$plain->setOption('tiff:preserve-compression', 'true');
if (!$plain->setImageCompression(Imagick::COMPRESSION_NO)) { throw new RuntimeException('No-compression setting failed'); }
if (!$plain->writeImage(__DIR__ . '/catalogue-plain.tif')) { throw new RuntimeException('TIFF write failed'); }
$packed = clone $source; $packed->setImageFormat('tiff'); $packed->setImageDepth(8);
$packed->setOption('tiff:preserve-compression', 'true');
if (!$packed->setImageCompression(Imagick::COMPRESSION_LZW)) { throw new RuntimeException('LZW setting failed'); }
if (!$packed->writeImage(__DIR__ . '/catalogue-lzw.tif')) { throw new RuntimeException('TIFF write failed'); }
$readPlain = new Imagick(__DIR__ . '/catalogue-plain.tif'); $readPacked = new Imagick(__DIR__ . '/catalogue-lzw.tif');
saveCompressionPNG($readPlain, 'plain-decoded.png'); saveCompressionPNG($readPacked, 'lzw-decoded.png');
saveCompressionComparison([$source, $readPlain, $readPacked], 'compression-tiff.png');
echo "compression-tiff.png\ncatalogue-plain.tif\ncatalogue-lzw.tif\nplain-decoded.png\nlzw-decoded.png\n";

После исходника показаны два TIFF, заново прочитанные Imagick. COMPRESSION_NO и COMPRESSION_LZW в этом примере включены для TIFF явной опцией tiff:preserve-compression=true. Файлы имеют разные способы хранения и размеры; оба декодируются в точные исходные пиксели. Одинаковая картинка здесь и есть полезное свойство сжатия без потерь. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-tiff.png
catalogue-plain.tif
catalogue-lzw.tif
plain-decoded.png
lzw-decoded.png

Хранить точный мастер и отдельно сделать JPEG для каталога

Исходник → TIFF LZW как точная копия пикселей → самостоятельная JPEG-копия quality 85. Повторные веб-версии следует создавать из исходника или мастера, чтобы не накапливать повторное JPEG-сжатие. Мастер сохраняет и SKU точно; JPEG нужно отдельно оценить на тексте и градиенте.

Хранить точный мастер и отдельно сделать JPEG для каталогаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$master = clone $source; $master->setImageFormat('tiff'); $master->setImageDepth(8);
$master->setOption('tiff:preserve-compression', 'true');
$master->setImageCompression(Imagick::COMPRESSION_LZW);
if (!$master->writeImage(__DIR__ . '/master-lzw.tif')) { throw new RuntimeException('Master write failed'); }
$web = clone $source; $web->setImageFormat('jpeg'); $web->setImageDepth(8);
$web->setImageCompression(Imagick::COMPRESSION_JPEG); $web->setImageCompressionQuality(85);
if (!$web->writeImage(__DIR__ . '/web-copy.jpg')) { throw new RuntimeException('Web copy write failed'); }
$readMaster = new Imagick(__DIR__ . '/master-lzw.tif'); $readWeb = new Imagick(__DIR__ . '/web-copy.jpg');
saveCompressionPNG($readMaster, 'master-decoded.png'); saveCompressionPNG($readWeb, 'web-decoded.png');
saveCompressionComparison([$source, $readMaster, $readWeb], 'compression-master-web.png');
echo "compression-master-web.png\nmaster-lzw.tif\nweb-copy.jpg\nmaster-decoded.png\nweb-decoded.png\n";

Исходник → TIFF LZW как точная копия пикселей → самостоятельная JPEG-копия quality 85. Повторные веб-версии следует создавать из исходника или мастера, чтобы не накапливать повторное JPEG-сжатие. Мастер сохраняет и SKU точно; JPEG нужно отдельно оценить на тексте и градиенте. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-master-web.png
master-lzw.tif
web-copy.jpg
master-decoded.png
web-decoded.png
Imagick::setImageCompressionQualityЗадаёт целое поле quality текущего изображения. Его смысл и использование определяет выбранный кодек.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageCompressionQuality(int $quality): bool

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$image->setImageFormat('jpeg');
$ok = $image->setImageCompressionQuality(85);
$image->writeImage(__DIR__ . '/web.jpg');

85 — параметр JPEG-кодирования в этом примере. setImageFormat выбирает формат; setImageCompressionQuality хранит число; writeImage выполняет кодирование и запись. __DIR__ — папка файла программы, . соединяет строки в путь. Смена настройки сама не меняет уже существующий JPEG на диске. PNG не становится JPEG от COMPRESSION_JPEG и не теряет alpha из-за числа 85.

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

Полный контракт и границы версии

Imagick::setImageCompressionQuality(int $quality): bool
ПараметрСмысл
$qualityОбязательный int. Для наших JPEG фиксированные 25/85/95 показывают разный компромисс, а 0 выбирает значение по умолчанию. Это не процент деталей. Для PNG семантика другая и данный путь установки поля не стал регулятором размера.

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

Для обычного JPEG-пути этой сборки 0 означает значение по умолчанию; в пробе файл затем прочитан как 92. Нельзя считать 0 универсально худшим качеством или 95 гарантией точного исходника. Для PNG кодировщик имеет отдельные настройки уровня/фильтра, а путь setImageCompressionQuality→writeImage в нашей пробе не передал число как регулятор: quality 10/90 дал одинаковые PNG. Это не утверждение, что любой способ настройки любого PNG обязан игнорироваться.

Официальный пример ниже — HTTP-функция: принимает путь и число, realpath получает путь, header сообщает тип ответа, getImageBlob отдаёт байты. header("Content-Type: image/jpg") не перекодирует изображение и не гарантирует JPEG. Наши CLI-программы явно выбирают формат и writeImage; сохранённый файл заново читают для проверки.

Оба setters на пустом объекте в проверке выбросили ImagickException. PHP-обёртка преобразует отказ внутреннего setter в это исключение; неверный PHP-тип может дать TypeError. Реализация не проверяет диапазон качества 0…100 и разрешённый список кодов за приложение. Для внешнего JPEG quality разумно самим разрешить целые 1…100 либо явно поддержанный 0; для compression — известные именованные константы. Это политика приложения, а не обещание автоматической валидации метода. Ошибка writeImage или отсутствие нужного кодека — отдельный отказ записи, который также надо обработать.

Возвращённое true подтверждает установку настройки, но не запись файла, уменьшение байтов, читаемость SKU, сохранение alpha или поддержку алгоритма данным кодеком. JPEG допускает потери и не сохраняет прозрачность; перед JPEG в задаче наклейки явно выбран белый фон. Наша PNG-наклейка хранит RGBA, а видимые составные PNG — RGB с 8 битами на компоненту. Это не индексированный PNG и не доказательство готовности к печати.

Весь официальный XML и исходные примеры
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagecompressionquality">
 <refnamediv>
  <refname>Imagick::setImageCompressionQuality</refname>
  <refpurpose>Sets the image compression quality</refpurpose>
 </refnamediv>

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

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>quality</parameter></term>
     <listitem>
      <para>
       The image compression quality as an integer
      </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>



 <refsect1 role="examples">
  &reftitle.examples;
  <para>
    <example>
      <title> <function>Imagick::setImageCompressionQuality</function></title>
      <programlisting role="php">
      <![CDATA[
<?php
function setImageCompressionQuality($imagePath, $quality) {
    $imagick = new \Imagick(realpath($imagePath));
    $imagick->setImageCompressionQuality($quality);
    header("Content-Type: image/jpg");
    echo $imagick->getImageBlob();
}

?>
]]>
      </programlisting>
    </example>
  </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
-->

Сравнить JPEG 25 и 95 на градиенте и мелком тексте

Три полных панели: исходник, декодированный JPEG 25, декодированный JPEG 95. Для этого рисунка у 25 сильнее заметны потери и меньше файл; 95 лучше сохраняет пиксели, но это всё ещё JPEG с потерями. Число не обозначает процент оставшихся деталей, а разница размеров зависит от изображения и кодека.

Сравнить JPEG 25 и 95 на градиенте и мелком текстеПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$low = clone $source; $low->setImageFormat('jpeg'); $low->setImageDepth(8);
$low->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$low->setImageCompressionQuality(25)) { throw new RuntimeException('Quality setting failed'); }
if (!$low->writeImage(__DIR__ . '/quality-25.jpg')) { throw new RuntimeException('JPEG write failed'); }
$high = clone $source; $high->setImageFormat('jpeg'); $high->setImageDepth(8);
$high->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$high->setImageCompressionQuality(95)) { throw new RuntimeException('Quality setting failed'); }
if (!$high->writeImage(__DIR__ . '/quality-95.jpg')) { throw new RuntimeException('JPEG write failed'); }
$readLow = new Imagick(__DIR__ . '/quality-25.jpg'); $readHigh = new Imagick(__DIR__ . '/quality-95.jpg');
saveCompressionPNG($readLow, 'quality-25-decoded.png'); saveCompressionPNG($readHigh, 'quality-95-decoded.png');
saveCompressionComparison([$source, $readLow, $readHigh], 'compression-jpeg-quality.png');
echo "compression-jpeg-quality.png\nquality-25.jpg\nquality-95.jpg\nquality-25-decoded.png\nquality-95-decoded.png\n";

Три полных панели: исходник, декодированный JPEG 25, декодированный JPEG 95. Для этого рисунка у 25 сильнее заметны потери и меньше файл; 95 лучше сохраняет пиксели, но это всё ещё JPEG с потерями. Число не обозначает процент оставшихся деталей, а разница размеров зависит от изображения и кодека. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-jpeg-quality.png
quality-25.jpg
quality-95.jpg
quality-25-decoded.png
quality-95-decoded.png

Доставить прозрачную PNG-наклейку и отдельно непрозрачный JPEG на белом

Панели: RGB-каталог как общий вход; наклейка на белом до JPEG; сохранённая RGBA PNG-наклейка поверх тёмной подложки; JPEG после явного наложения на белый и повторного чтения. В PNG сохранены alpha и отверстие ручки. JPEG хранит выбранный белый фон и не может затем раскрыть его как прозрачность. Одинаковое quality 85 не делает форматы одинаковыми.

Доставить прозрачную PNG-наклейку и отдельно непрозрачный JPEG на беломПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$sticker = clone $product; $sticker->setImageFormat('png'); $sticker->setImageDepth(8); $sticker->setOption('png:color-type', '6');
$sticker->setImageCompression(Imagick::COMPRESSION_ZIP); $sticker->setImageCompressionQuality(85);
if (!$sticker->writeImage(__DIR__ . '/sticker-preserved.png')) { throw new RuntimeException('Sticker write failed'); }
$white = compressionPreview($product, 'white');
$jpeg = clone $white; $jpeg->setImageFormat('jpeg'); $jpeg->setImageDepth(8);
$jpeg->setImageCompression(Imagick::COMPRESSION_JPEG);
if (!$jpeg->setImageCompressionQuality(85)) { throw new RuntimeException('Quality setting failed'); }
if (!$jpeg->writeImage(__DIR__ . '/sticker-white.jpg')) { throw new RuntimeException('Opaque JPEG write failed'); }
$readPNG = new Imagick(__DIR__ . '/sticker-preserved.png'); $readJPEG = new Imagick(__DIR__ . '/sticker-white.jpg');
saveCompressionPNG($readJPEG, 'sticker-jpeg-decoded.png');
$darkPreview = compressionPreview($readPNG, '#243c4d');
saveCompressionComparison([$source, $white, $darkPreview, $readJPEG], 'compression-alpha-format.png');
echo "compression-alpha-format.png\nsticker-preserved.png\nsticker-white.jpg\nsticker-jpeg-decoded.png\n";

Панели: RGB-каталог как общий вход; наклейка на белом до JPEG; сохранённая RGBA PNG-наклейка поверх тёмной подложки; JPEG после явного наложения на белый и повторного чтения. В PNG сохранены alpha и отверстие ручки. JPEG хранит выбранный белый фон и не может затем раскрыть его как прозрачность. Одинаковое quality 85 не делает форматы одинаковыми. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-alpha-format.png
sticker-preserved.png
sticker-white.jpg
sticker-jpeg-decoded.png
Imagick::getImageCompressionQualityЧитает целое поле quality текущего изображения; после чтения файла значение зависит от формата и его декодера.

PECL imagick 2 >= 2.2.2, PECL imagick 3 · imagick

Imagick::getImageCompressionQuality(): int

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

$image — уже загруженное изображение. $ вводит имя переменной; = присваивает результат; -> вызывает метод объекта; круглые скобки содержат аргументы; запятая их разделяет; ; завершает инструкцию. Imagick:: обращается к именованной константе класса. Строки в кавычках — текст, 85 — целое число. Setter меняет настройку этого объекта и возвращает true при успехе, а не картинку.

$quality = $image->getImageCompressionQuality();
echo $quality;

Читаем целое число без аргументов. Для текущего объекта после установки 85 это 85. После JPEG декодер оценивает число по его таблицам квантования; после нашего PNG возвращается 0 при точных пикселях. Для отчёта также нужен $image->getImageFormat(), а для размера файла — filesize(путь). Getter не выполняет эти проверки за нас.

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

Полный контракт и границы версии

Imagick::getImageCompressionQuality(): int
ПараметрСмысл
Нет аргументовПустые скобки (). Возвращает int, а не bool, размер файла или оценку читаемости. 0 не следует переводить как «качество 0%».

Gets the current image's compression quality Доступность: PECL imagick 2 >= 2.2.2, PECL imagick 3. Возврат: Returns integer describing the images compression quality Таблицы изменений у этих трёх XML-записей отсутствуют. Весь официальный XML со всеми примерами сохранён ниже.

Метод относится к текущему изображению. До записи он читает установленное поле; после JPEG библиотека оценивает quality по таблицам квантования файла. Это не исходный авторский параметр с доказанной историей и не процент сохранённых деталей. В PNG число 0 в нашем отчёте не означает плохие пиксели. На пустом Imagick в этой реализации getter вернул 0, тогда как setters выбросили ImagickException. Раздел ошибок в официальном XML getter отсутствует; не добавляем выдуманную гарантию исключения.

Оба setters на пустом объекте в проверке выбросили ImagickException. PHP-обёртка преобразует отказ внутреннего setter в это исключение; неверный PHP-тип может дать TypeError. Реализация не проверяет диапазон качества 0…100 и разрешённый список кодов за приложение. Для внешнего JPEG quality разумно самим разрешить целые 1…100 либо явно поддержанный 0; для compression — известные именованные константы. Это политика приложения, а не обещание автоматической валидации метода. Ошибка writeImage или отсутствие нужного кодека — отдельный отказ записи, который также надо обработать.

Возвращённое true подтверждает установку настройки, но не запись файла, уменьшение байтов, читаемость SKU, сохранение alpha или поддержку алгоритма данным кодеком. JPEG допускает потери и не сохраняет прозрачность; перед JPEG в задаче наклейки явно выбран белый фон. Наша PNG-наклейка хранит RGBA, а видимые составные PNG — RGB с 8 битами на компоненту. Это не индексированный PNG и не доказательство готовности к печати.

Весь официальный XML и исходные примеры
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagecompressionquality">
 <refnamediv>
  <refname>Imagick::getImageCompressionQuality</refname>
  <refpurpose>Gets the current image's compression quality</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>int</type><methodname>Imagick::getImageCompressionQuality</methodname>
   <void/>
  </methodsynopsis>

  <para>
   Gets the current image's compression quality
  </para>
 </refsect1>

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

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns integer describing the images compression quality
  </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
-->

Прочитать quality до записи и после JPEG с настройкой 0

В текущем объекте установили 0. В проверенном JPEG-кодеке это выбор значения по умолчанию, а не уничтожение качества: после чтения файла getter оценил 92 по таблицам квантования JPEG. Getter не сравнивает картинку с исходником и не обнаруживает потерянный текст.

Прочитать quality до записи и после JPEG с настройкой 0Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$web = clone $source; $web->setImageFormat('jpeg'); $web->setImageDepth(8);
$web->setImageCompression(Imagick::COMPRESSION_JPEG); $web->setImageCompressionQuality(0);
$liveQuality = $web->getImageCompressionQuality();
if (!$web->writeImage(__DIR__ . '/default-quality.jpg')) { throw new RuntimeException('JPEG write failed'); }
$loaded = new Imagick(__DIR__ . '/default-quality.jpg');
$readQuality = $loaded->getImageCompressionQuality();
saveCompressionPNG($loaded, 'default-decoded.png');
saveCompressionComparison([$source, $loaded], 'compression-get-default.png');
echo "compression-get-default.png\ndefault-quality.jpg\ndefault-decoded.png\n";
printf("live-quality=%d read-quality=%d\n", $liveQuality, $readQuality);

В текущем объекте установили 0. В проверенном JPEG-кодеке это выбор значения по умолчанию, а не уничтожение качества: после чтения файла getter оценил 92 по таблицам квантования JPEG. Getter не сравнивает картинку с исходником и не обнаруживает потерянный текст. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-get-default.png
default-quality.jpg
default-decoded.png
live-quality=0 read-quality=92

Составить отчёт о JPEG и PNG, не объявляя PNG с quality 0 испорченным

После исходника показаны прочитанный JPEG и PNG-наклейка на тёмном. Отчёт даёт JPEG 85, PNG 0 и активную alpha у PNG. Поэтому правило «отклонить любой файл при quality<80» неверно для этих двух форматов. Сначала читаем фактический формат; отдельно проверяем пиксели, размер файла, прозрачность и требования к доставке.

Составить отчёт о JPEG и PNG, не объявляя PNG с quality 0 испорченнымПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__ . '/compression-fixture.php';
[$source, $product] = loadCompressionInputs();
$jpeg = clone $source; $jpeg->setImageFormat('jpeg'); $jpeg->setImageDepth(8);
$jpeg->setImageCompression(Imagick::COMPRESSION_JPEG); $jpeg->setImageCompressionQuality(85);
if (!$jpeg->writeImage(__DIR__ . '/incoming-catalogue.jpg')) { throw new RuntimeException('JPEG write failed'); }
$png = clone $product; $png->setImageFormat('png'); $png->setImageDepth(8); $png->setOption('png:color-type', '6');
$png->setImageCompression(Imagick::COMPRESSION_ZIP); $png->setImageCompressionQuality(85);
if (!$png->writeImage(__DIR__ . '/incoming-sticker.png')) { throw new RuntimeException('PNG write failed'); }
$readJPEG = new Imagick(__DIR__ . '/incoming-catalogue.jpg'); $readPNG = new Imagick(__DIR__ . '/incoming-sticker.png');
$jpegQuality = $readJPEG->getImageCompressionQuality(); $pngQuality = $readPNG->getImageCompressionQuality();
saveCompressionPNG($readJPEG, 'incoming-jpeg-decoded.png');
$pngPreview = compressionPreview($readPNG, '#243c4d');
saveCompressionComparison([$source, $readJPEG, $pngPreview], 'compression-format-report.png');
echo "compression-format-report.png\nincoming-catalogue.jpg\nincoming-sticker.png\nincoming-jpeg-decoded.png\n";
printf("JPEG quality-field=%d; PNG quality-field=%d alpha=%d\n", $jpegQuality, $pngQuality, (int)$readPNG->getImageAlphaChannel());

После исходника показаны прочитанный JPEG и PNG-наклейка на тёмном. Отчёт даёт JPEG 85, PNG 0 и активную alpha у PNG. Поэтому правило «отклонить любой файл при quality<80» неверно для этих двух форматов. Сначала читаем фактический формат; отдельно проверяем пиксели, размер файла, прозрачность и требования к доставке. Для запуска в одной папке нужны example.php, compression-fixture.php, source.png.b64 и product.png.b64; сохраните также остальные файлы ZIP. Команда: php example.php с Imagick и поддержкой JPEG/PNG/TIFF. Код не требует сети или шрифтов. Выходные JPEG/TIFF и PNG создаются при запуске; они не являются входными файлами ZIP. Полный helper открыт ниже.

Ожидаемый вывод
compression-format-report.png
incoming-catalogue.jpg
incoming-sticker.png
incoming-jpeg-decoded.png
JPEG quality-field=85; PNG quality-field=0 alpha=1
Источники и обсуждения

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

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

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

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