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

Дерево руководства
Глава 430 · После первых изображений, файлов и объектов
Gmagick: progressive JPEG, Adam7 PNG и детализация цвета
Проверить структуру записанного файла, сравнить 4:4:4/4:2:2 на цветных границах и выбрать явный рецепт экспорта.
Проверить image-настройку по настоящему JPEG
Нужно progressive JPEG, но одного успешного setter недостаточно. В этой сборке setImageInterlaceScheme(LINE) и getter согласованно возвращают LINE, однако реальный JPEG записывается baseline. На странице виден его декодированный PNG; тип кодирования доказывает SOF0 в сохранённом JPEG, а не внешний вид готовой картинки.

Файлы именно этого выполненного примера: Скачать настоящий baseline JPEG: image-setting.jpg. PNG выше — декодированные превью, не демонстрация порядка загрузки JPEG.
$image = new Gmagick(__DIR__ . "/encoding.ppm");
$image->setImageFormat("JPEG");
$image->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);
$setting = $image->getImageInterlaceScheme();
$image->writeImage(__DIR__ . "/image-setting.jpg");Этот короткий пример показывает именно image-настройку. Контракт принимает int INTERLACE_* и возвращает Gmagick, getter возвращает int. В проверенном Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 значение перед записью равно LINE, после открытия JPEG — NO. Полная программа разбирает SOF0/SOF2 маленькой функцией из helper; так видно отличие состояния объекта от результата кодера. Работающий способ задания кодеру показан следующим шагом.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
$image=new Gmagick(__DIR__.'/encoding.ppm');$image->setImageDepth(8);$image->setImageFormat('JPEG');$image->setCompressionQuality(80);
$image->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);$requested=$image->getImageInterlaceScheme();
$image->writeImage(__DIR__.'/gm100-export-image-interlace-image-setting.jpg');$reopened=new Gmagick(__DIR__.'/gm100-export-image-interlace-image-setting.jpg');$actualGetter=$reopened->getImageInterlaceScheme();
$header=gmJpegHeader('gm100-export-image-interlace-image-setting.jpg');gmPng($reopened,'gm100-export-image-interlace-decoded.png');
gmReport('gm100-export-image-interlace',["gmagick.setimageinterlacescheme", "gmagick.getimageinterlacescheme"],["gm100-export-image-interlace-decoded.png"],['setting_roundtrip'=>$requested===Gmagick::INTERLACE_LINE,'saved_baseline'=>$header["progressive"]===false&&$header["sof"]===192,'reread_differs'=>$actualGetter!==$requested],$errors??[],['requested'=>$requested,'reread_getter'=>$actualGetter,'jpeg_header'=>$header],[]);
echo "image-interlace: requested=LINE saved=baseline getter-alone=insufficient\n";
Ожидаемый результат
image-interlace: requested=LINE saved=baseline getter-alone=insufficient
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: утверждать «файл progressive», потому что getter вернул LINE. Решение: проверить структуру созданного JPEG или открыть его независимым анализатором. Полная загрузка baseline и progressive может давать одинаковые пиксели, поэтому screenshot конечного изображения не подтверждает порядок появления сканов.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Записать настоящий progressive JPEG
Запишем два реальных JPEG с одинаковым качеством 80 и субдискретизацией 4:4:4: baseline и progressive. Их конечные превью могут совпадать. Отличается структура файла: SOF0 и SOF2, которая позволяет декодеру по-разному обрабатывать поступающие данные.


Файлы именно этого выполненного примера: Скачать настоящий baseline JPEG: baseline.jpg; Скачать настоящий progressive JPEG: progressive.jpg. PNG выше — декодированные превью, не демонстрация порядка загрузки JPEG.
$image = new Gmagick(__DIR__ . "/encoding.ppm");
$image->setImageFormat("JPEG");
$image->setCompressionQuality(80);
$image->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);
$image->setInterlaceScheme(Gmagick::INTERLACE_LINE);
$image->writeImage(__DIR__ . "/progressive.jpg");setInterlaceScheme — отдельный существующий runtime-метод настройки Wand/кодера, подтверждённый текущим C и запуском. Он не подменяет официальную карточку setImageInterlaceScheme и не записан как новый документированный метод PHP.net. В полном сравнении обеим копиям задаётся одинаковый sampling, затем одна получает NO, другая LINE на обоих уровнях. У результата проверяется настоящий JPEG-заголовок. PNG-превью создаётся после чтения этого JPEG, а не из ещё несохранённого объекта.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
$source=new Gmagick(__DIR__.'/encoding.ppm');$baseline=clone $source;$progressive=clone $source;
foreach([$baseline,$progressive]as $image){$image->setImageDepth(8);$image->setImageFormat('JPEG');$image->setCompressionQuality(80);$image->setSamplingFactors([1.0,1.0,1.0]);}
$baseline->setImageInterlaceScheme(Gmagick::INTERLACE_NO);$baseline->setInterlaceScheme(Gmagick::INTERLACE_NO);
$progressive->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);$progressive->setInterlaceScheme(Gmagick::INTERLACE_LINE);
$selected=$progressive->getImageInterlaceScheme();$baseline->writeImage(__DIR__.'/gm100-export-progressive-baseline.jpg');$progressive->writeImage(__DIR__.'/gm100-export-progressive-progressive.jpg');
$a=gmJpegHeader('gm100-export-progressive-baseline.jpg');$b=gmJpegHeader('gm100-export-progressive-progressive.jpg');
gmPng(new Gmagick(__DIR__.'/gm100-export-progressive-baseline.jpg'),'gm100-export-progressive-baseline-view.png');gmPng(new Gmagick(__DIR__.'/gm100-export-progressive-progressive.jpg'),'gm100-export-progressive-progressive-view.png');
gmReport('gm100-export-progressive',["gmagick.setimageinterlacescheme", "gmagick.getimageinterlacescheme", "gmagick.setsamplingfactors"],["gm100-export-progressive-baseline-view.png", "gm100-export-progressive-progressive-view.png"],['setting_line'=>$selected===Gmagick::INTERLACE_LINE,'actual_header_modes'=>!$a["progressive"]&&$b["progressive"],'same_sampling'=>$a["sampling_factors"]===$b["sampling_factors"]],$errors??[],['baseline'=>$a,'progressive'=>$b],["Gmagick::setInterlaceScheme"]);
echo "jpeg: baseline=SOF0 progressive=SOF2 sampling=444\n";
Ожидаемый результат
jpeg: baseline=SOF0 progressive=SOF2 sampling=444
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: гарантировать, что progressive всегда меньше. Решение: измерять конкретные файлы; такой гарантии нет. Эффект постепенного появления зависит также от браузера, декодера и доставки данных. Здесь доказан формат progressive, а сетевой эксперимент с медленной загрузкой не имитируется статическими картинками.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Записать PNG Adam7 и проверить IHDR
Для схемы с резкими цветами пригодится PNG без потери пикселей. Сохраним обычный PNG и реальный Adam7. Они показывают одну и ту же конечную мишень; в IHDR у первого interlace=0, у второго 1. Этот байт относится к организации данных PNG.


$image = new Gmagick(__DIR__ . "/encoding.ppm");
$image->setImageDepth(8);
$image->setImageFormat("PNG");
$image->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);
$image->setInterlaceScheme(Gmagick::INTERLACE_LINE);
$image->writeImage(__DIR__ . "/adam7.png");Для нашей сборки важна отдельная настройка Wand setInterlaceScheme; image-only LINE в discovery не изменил IHDR. После повторного чтения настоящего Adam7 getImageInterlaceScheme здесь вернул 0, поэтому getter не заменяет проверку заголовка. Полная программа читает сигнатуру PNG, IHDR и значение interlace, затем сравнивает пиксельные подписи декодированных файлов. Adam7 не добавляет анимацию и не меняет размер холста.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
$source=new Gmagick(__DIR__.'/encoding.ppm');$plain=clone $source;$adam=clone $source;
foreach([$plain,$adam]as $image){$image->setImageDepth(8);$image->setImageFormat('PNG');}
$plain->setImageInterlaceScheme(Gmagick::INTERLACE_NO);$plain->setInterlaceScheme(Gmagick::INTERLACE_NO);
$adam->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);$adam->setInterlaceScheme(Gmagick::INTERLACE_LINE);$selected=$adam->getImageInterlaceScheme();
$plain->writeImage(__DIR__.'/gm100-export-png-interlace-plain.png');$adam->writeImage(__DIR__.'/gm100-export-png-interlace-adam7.png');
$flags=[gmPngInterlace('gm100-export-png-interlace-plain.png'),gmPngInterlace('gm100-export-png-interlace-adam7.png')];$reopened=new Gmagick(__DIR__.'/gm100-export-png-interlace-adam7.png');$reread=$reopened->getImageInterlaceScheme();
gmReport('gm100-export-png-interlace',["gmagick.setimageinterlacescheme", "gmagick.getimageinterlacescheme"],["gm100-export-png-interlace-plain.png", "gm100-export-png-interlace-adam7.png"],['selected_line'=>$selected===Gmagick::INTERLACE_LINE,'actual_ihdr_flags'=>$flags===[0,1],'pixels_identical'=>(new Gmagick(__DIR__."/gm100-export-png-interlace-plain.png"))->getImageSignature()===$reopened->getImageSignature()],$errors??[],['ihdr_interlace'=>$flags,'reread_getter'=>$reread],["Gmagick::setInterlaceScheme"]);
echo "png: plain=0 adam7=1 final-pixels=identical\n";
Ожидаемый результат
png: plain=0 adam7=1 final-pixels=identical
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: получить меньший PNG за счёт interlace. Решение: сравнить реальные размеры, а не обещать уменьшение: на нашей мишени Adam7 получился больше. Для пиксельной графики сначала выбирайте подходящий формат и требования к доставке, а затем включайте нужный порядок проходов.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Сравнить реальные JPEG 4:4:4 и 4:2:2
Тонкие красно-синие и зелёно-жёлтые полосы позволяют увидеть влияние JPEG-субдискретизации. Сохраним одинаковое качество 80, но разные sampling-настройки. В JPEG4:2:2 цветная информация по горизонтали реже, чем в 4:4:4, поэтому цветные границы нашей мишени меняются заметнее.



Файлы именно этого выполненного примера: Скачать настоящий baseline JPEG: 444.jpg; Скачать настоящий baseline JPEG: 422.jpg. PNG выше — декодированные превью, не демонстрация порядка загрузки JPEG.
$image = new Gmagick(__DIR__ . "/encoding.ppm");
$image->setImageFormat("JPEG");
$image->setCompressionQuality(80);
$image->setSamplingFactors([2.0, 1.0, 1.0]);
$configured = $image->getSamplingFactors();
$image->writeImage(__DIR__ . "/sample422.jpg");PHP.net описывает массив float по цветовым компонентам в RGB-порядке. Нельзя механически перенести строки «2x2» из Imagick: этот Gmagick setter преобразует элементы в double. В проверенной сборке массив[1,1,1] дал SOF-факторы 1×1,1×1,1×1 —4:4:4; [2,1,1] дал 2×1,1×1,1×1 —4:2:2. Это не 4:2:0. Реальные JPEG-компоненты относятся к кодированному представлению; изменение sampling не равнозначно смене colorspace входа.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
$source=new Gmagick(__DIR__.'/encoding.ppm');$full=clone $source;$reduced=clone $source;
foreach([$full,$reduced]as $image){$image->setImageDepth(8);$image->setImageFormat('JPEG');$image->setCompressionQuality(80);}
$full->setSamplingFactors([1.0,1.0,1.0]);$reduced->setSamplingFactors([2.0,1.0,1.0]);$configured=[$full->getSamplingFactors(),$reduced->getSamplingFactors()];
$full->writeImage(__DIR__.'/gm100-export-sampling-444.jpg');$reduced->writeImage(__DIR__.'/gm100-export-sampling-422.jpg');$a=gmJpegHeader('gm100-export-sampling-444.jpg');$b=gmJpegHeader('gm100-export-sampling-422.jpg');
gmPng($source,'gm100-export-sampling-source.png');gmPng(new Gmagick(__DIR__.'/gm100-export-sampling-444.jpg'),'gm100-export-sampling-444-view.png');gmPng(new Gmagick(__DIR__.'/gm100-export-sampling-422.jpg'),'gm100-export-sampling-422-view.png');
gmReport('gm100-export-sampling',["gmagick.setsamplingfactors", "gmagick.getsamplingfactors"],["gm100-export-sampling-source.png", "gm100-export-sampling-444-view.png", "gm100-export-sampling-422-view.png"],['actual_444'=>$a["sampling_factors"]===[[1,1],[1,1],[1,1]],'actual_422'=>$b["sampling_factors"]===[[2,1],[1,1],[1,1]],'decoded_pixels_differ'=>(new Gmagick(__DIR__."/gm100-export-sampling-444.jpg"))->getImageSignature()!==(new Gmagick(__DIR__."/gm100-export-sampling-422.jpg"))->getImageSignature()],$errors??[],['getters'=>$configured,'full'=>$a,'reduced'=>$b],[]);
echo "sampling: numeric111=444 numeric211=422 confirmed=SOF\n";
Ожидаемый результат
sampling: numeric111=444 numeric211=422 confirmed=SOF
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: считать число 80 единственной характеристикой качества JPEG. Решение: вместе с качеством фиксировать sampling и оценивать важные детали. Для логотипа или схемы с мелкими цветными линиями полезно сравнить PNG без потерь и JPEG4:4:4; для фотографии выбор зависит от содержания и измеренного размера.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Отделить настройки sampling от заголовка файла
Getter sampling не оказался паспортом JPEG. На новом изображении он вернул[], после setSamplingFactors([2,1,1]) — индексированный массив[2,1], а после открытия сохранённого JPEG снова[]. При этом SOF файла содержит три компонента и подтверждает 4:2:2.

Файлы именно этого выполненного примера: Скачать настоящий baseline JPEG: output.jpg. PNG выше — декодированные превью, не демонстрация порядка загрузки JPEG.
$image = new Gmagick(__DIR__ . "/encoding.ppm");
$image->setSamplingFactors([2.0, 1.0, 1.0]);
$configured = $image->getSamplingFactors();
$image->setImageFormat("JPEG");
$image->writeImage(__DIR__ . "/output.jpg");
$loaded = new Gmagick(__DIR__ . "/output.jpg");
$afterRead = $loaded->getSamplingFactors();Официальный текст getter обещает associative array с горизонтальными и вертикальными коэффициентами; текущий C формирует обычный индексированный массив float. Наблюдаемая длина и пустой readback показаны явно в JSON. Поэтому пользовательский отчёт хранит отдельно requested/configured и фактические sampling_factors из SOF. Пустой getter после чтения не означает, что в JPEG отсутствуют коэффициенты выборки.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
$image=new Gmagick(__DIR__.'/encoding.ppm');$before=$image->getSamplingFactors();$ret=$image->setSamplingFactors([2.0,1.0,1.0]);$configured=$image->getSamplingFactors();
$image->setImageDepth(8);$image->setImageFormat('JPEG');$image->setCompressionQuality(80);$image->writeImage(__DIR__.'/gm100-export-sampling-readback-output.jpg');
$loaded=new Gmagick(__DIR__.'/gm100-export-sampling-readback-output.jpg');$readback=$loaded->getSamplingFactors();$header=gmJpegHeader('gm100-export-sampling-readback-output.jpg');gmPng($loaded,'gm100-export-sampling-readback-decoded.png');
gmReport('gm100-export-sampling-readback',["gmagick.setsamplingfactors", "gmagick.getsamplingfactors"],["gm100-export-sampling-readback-decoded.png"],['same_object'=>$ret===$image,'getter_shape_observed'=>$before===[]&&$configured===[2.0,1.0]&&$readback===[],'file_contains_422'=>$header["sampling_factors"]===[[2,1],[1,1],[1,1]]],$errors??[],['before'=>$before,'configured'=>$configured,'reopened'=>$readback,'actual_file'=>$header],[]);
echo "sampling-readback: configured=2-values reopened=empty file=422\n";
Ожидаемый результат
sampling-readback: configured=2-values reopened=empty file=422
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: восстановить параметры чужого JPEG для повторного экспорта. Решение: прочитать реальную структуру или использовать проверенный анализатор, затем задать новый рецепт явно. Не переносить [] в новый экспорт под предположением, что это сохранит старую субдискретизацию.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Выбрать экспорт для цветной графики и веб-превью
Сервису удобнее принимать смысловые имена пресетов, чем произвольные наборы констант. sharp сохраняет цветные детали через 4:4:4, compact использует 4:2:2; оба создают настоящий progressive JPEG. Названия — наш выбор интерфейса, а реальные свойства записываются в отчёт.


Файлы именно этого выполненного примера: Скачать настоящий progressive JPEG: sharp.jpg; Скачать настоящий progressive JPEG: compact.jpg. PNG выше — декодированные превью, не демонстрация порядка загрузки JPEG.
$source = new Gmagick(__DIR__ . "/encoding.ppm");
$sharp = exportJpeg($source, "sharp", "sharp.jpg");
$compact = exportJpeg($source, "compact", "compact.jpg");
echo $sharp["actual"]["progressive"] ? "progressive" : "baseline";Функция exportJpeg полностью приведена ниже. Белый список допускает два пресета; clone защищает исходник от настроек соседнего варианта. Далее явно задаются формат, глубина, качество, sampling и оба уровня interlace, выполняется запись и разбирается SOF. Никакой метод не вызывается по произвольной пользовательской строке. Слово compact здесь обозначает рецепт, а не обещание, что каждый конкретный файл окажется меньше.
<?php
declare(strict_types=1);
require __DIR__.'/gm100-export-fixture.php';
gmRestore();
function exportJpeg(Gmagick $source,string $preset,string $file):array {
if(!in_array($preset,['sharp','compact'],true))throw new InvalidArgumentException('Choose sharp or compact');
$copy=clone $source;$copy->setImageDepth(8);$copy->setImageFormat('JPEG');$copy->setCompressionQuality(80);
$copy->setSamplingFactors($preset==='sharp'?[1.0,1.0,1.0]:[2.0,1.0,1.0]);$factors=$copy->getSamplingFactors();
$copy->setImageInterlaceScheme(Gmagick::INTERLACE_LINE);$copy->setInterlaceScheme(Gmagick::INTERLACE_LINE);$setting=$copy->getImageInterlaceScheme();
$copy->writeImage(__DIR__.'/'.$file);return ['preset'=>$preset,'setting'=>$setting,'configured'=>$factors,'actual'=>gmJpegHeader($file)];
}
$source=new Gmagick(__DIR__.'/encoding.ppm');$sharp=exportJpeg($source,'sharp','gm100-export-export-policy-sharp.jpg');$compact=exportJpeg($source,'compact','gm100-export-export-policy-compact.jpg');
gmPng(new Gmagick(__DIR__.'/gm100-export-export-policy-sharp.jpg'),'gm100-export-export-policy-sharp-view.png');gmPng(new Gmagick(__DIR__.'/gm100-export-export-policy-compact.jpg'),'gm100-export-export-policy-compact-view.png');
$errors=['unknown_preset'=>gmTry(fn()=>exportJpeg($source,'other','unused.jpg'))];
gmReport('gm100-export-export-policy',["gmagick.setsamplingfactors", "gmagick.getsamplingfactors", "gmagick.setimageinterlacescheme", "gmagick.getimageinterlacescheme"],["gm100-export-export-policy-sharp-view.png", "gm100-export-export-policy-compact-view.png"],['both_progressive'=>$sharp["actual"]["progressive"]&&$compact["actual"]["progressive"],'different_sampling'=>$sharp["actual"]["sampling_factors"]!==$compact["actual"]["sampling_factors"]],$errors??[],['sharp'=>$sharp,'compact'=>$compact],["Gmagick::setInterlaceScheme"]);
echo "export: sharp=progressive444 compact=progressive422 unknown=rejected\n";
Ожидаемый результат
export: sharp=progressive444 compact=progressive422 unknown=rejected
Распакуйте архив и выполните php example.php. Вложенные .b64 содержат все входы; helper проверяет SHA256 и восстанавливает PPM. gmPng сохраняет копию в PNG8. gmJpegHeader читает SOF0/SOF2 и коэффициенты компонентов из настоящего JPEG, gmPngInterlace читает IHDR. metrics.json содержит результаты и проверки. JPEG/PNG и квитанции появятся после выполнения; исходные файлы не берутся из внешней папки.
Упражнение: добавить режим для маленькой диаграммы с текстом. Решение: сначала сравнить выход PNG без потерь с JPEG-пресетами на её деталях, затем добавить отдельное осмысленное правило. Конечные PNG-превью полезны для оценки искажений, но не показывают progressive-проходы загрузки.
Связанные шаги: имена и путь записи, кодирование JPEG/PNG, окружение и рабочий объект, качество, метаданные и глубина файла.
Из реальной задачи разработчика
How can I save a JPG image in 4:2:0 colorspace with Imagick?. Нужно получить JPEG с меньшей цветовой выборкой; попытка менять colorspace испортила цвета. Разделяем преобразование пространства и JPEG sampling. Для текущего Gmagick используем массивы чисел, проверяем факторы каждого SOF-компонента и честно называем [2,1,1] схемой4:2:2 в этой сборке. Показываем цветные границы реальных декодированных файлов, не переносим строки Imagick или обещания4:2:0 без проверки.
Из реальной задачи разработчика
Why doesn't setImageInterlaceScheme() make a jpeg progressive?. Автор Gmagick выставил image interlace и получил подтверждение getter, но JPEG не стал progressive. Наше решение отдельно показывает состояние текущего изображения и настройку кодера Wand. Программа сохраняет настоящий baseline и progressive JPEG, проверяет SOF0/SOF2 и даёт ссылки на реальные файлы. Работающий setInterlaceScheme назван отдельным runtime API, без подмены официальной карточки image-setter.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Gmagick::getimageinterlaceschemeПрочитать interlace-состояние текущего изображения
PECL gmagick >= Unknown · gmagick
Gmagick::getimageinterlacescheme(): intБез аргументов возвращает int — схему interlace текущего изображения. Сравнивайте с именованными INTERLACE_*, а не считайте число готовым описанием структуры файла. На нашей сборке getter после image-setter возвращает LINE, но JPEG всё ещё может быть baseline; после чтения настоящего Adam7 PNG получено 0. Поэтому вывод о progressive/Adam7 делается по реальному JPEG SOF или PNG IHDR. Getter полезен для наблюдения состояния объекта, но не заменяет проверку выполненного экспорта.
Gmagick::getimageinterlacescheme(): intПараметров нет: вызов записывается с пустыми скобками.
Официальная ошибка — GmagickException. Дополнительно PHP проверяет типы аргументов; прикладные ограничения пути и пресета в наших функциях дают InvalidArgumentException до вызова библиотеки. Не смешивайте эти уровни проверки.
Два самостоятельных применения: Проверить image-настройку по настоящему JPEG; Записать PNG Adam7 и проверить IHDR.
Отметка PHP.net: PECL gmagick >= Unknown. Unknown не сообщает известную минимальную версию. Наблюдения относятся к PHP 8.3.6/Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 Q16; поведение экспортного кодера подтверждается реальными файлами.
Gmagick::getsamplingfactorsПрочитать sampling-настройку, не подменяя анализ JPEG
PECL gmagick >= Unknown · gmagick
Gmagick::getsamplingfactors(): arrayБез аргументов возвращает array. Официальное описание говорит об ассоциативном массиве горизонтальных и вертикальных коэффициентов; текущий C добавляет числа double с последовательными индексами. В наших программах после [2,1,1] получено [2.0,1.0], а после открытия JPEG — пустой массив. При этом сам файл содержит три компонента SOF и реальную схему 4:2:2. Разделяйте configured getter и фактические sampling_factors в заголовке; отсутствие значений в getter не означает отсутствие субдискретизации в файле.
Gmagick::getsamplingfactors(): arrayПараметров нет: вызов записывается с пустыми скобками.
Официальная ошибка — GmagickException. Дополнительно PHP проверяет типы аргументов; прикладные ограничения пути и пресета в наших функциях дают InvalidArgumentException до вызова библиотеки. Не смешивайте эти уровни проверки.
Два самостоятельных применения: Сравнить реальные JPEG 4:4:4 и 4:2:2; Отделить настройки sampling от заголовка файла.
Отметка PHP.net: PECL gmagick >= Unknown. Unknown не сообщает известную минимальную версию. Наблюдения относятся к PHP 8.3.6/Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 Q16; поведение экспортного кодера подтверждается реальными файлами.
Gmagick::setimageinterlaceschemeЗадать interlace для изображения и проверить экспорт
PECL gmagick >= Unknown · gmagick
Gmagick::setimageinterlacescheme(int $interlace): GmagickОбязательный int interlace выбирается из Gmagick::INTERLACE_*. Метод устанавливает схему текущего изображения и возвращает Gmagick. Среди констант есть UNDEFINED, NO, LINE, PLANE и PARTITION; их смысл при записи зависит от формата и кодера. В Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 image-only LINE/PLANE не сделали JPEG progressive, хотя getter прочитал настройку. Рабочие программы дополнительно вызывают подтверждённый runtime-метод Wand setInterlaceScheme(LINE), затем проверяют настоящий файл. Эти два API показаны раздельно; наличие image-настройки не объявляется доказательством успешного кодирования.
Gmagick::setimageinterlacescheme(int $interlace): Gmagick| Параметр | Тип и обязательность | Назначение |
|---|---|---|
| $interlace | int; обязательный | Одна из именованных констант Gmagick::INTERLACE_*; результат кодирования проверяется отдельно. |
Официальная ошибка — GmagickException. Дополнительно PHP проверяет типы аргументов; прикладные ограничения пути и пресета в наших функциях дают InvalidArgumentException до вызова библиотеки. Не смешивайте эти уровни проверки.
Два самостоятельных применения: Проверить image-настройку по настоящему JPEG; Записать настоящий progressive JPEG.
Отметка PHP.net: PECL gmagick >= Unknown. Unknown не сообщает известную минимальную версию. Наблюдения относятся к PHP 8.3.6/Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 Q16; поведение экспортного кодера подтверждается реальными файлами.
Gmagick::setsamplingfactorsЗадать числовые коэффициенты и проверить SOF
PECL gmagick >= Unknown · gmagick
Gmagick::setsamplingfactors(array $factors): GmagickПринимает обязательный array factors. PHP.net описывает массив float для цветовых компонентов в RGB-порядке; возвращает Gmagick. Текущий C преобразует элементы в double, поэтому строки вида «2x2» из примеров Imagick здесь не являются переносимым рецептом. Наблюдаемые числовые массивы: [1.0,1.0,1.0] создаёт JPEG с факторами 1×1,1×1,1×1 (4:4:4), [2.0,1.0,1.0] —2×1,1×1,1×1 (4:2:2). Не называйте второй 4:2:0. Полные программы проверяют настоящий заголовок и показывают декодированные цветные границы. Sampling меняет пространственную детализацию цветовых компонент JPEG, а не заменяет преобразование colorspace.
Gmagick::setsamplingfactors(array $factors): Gmagick| Параметр | Тип и обязательность | Назначение |
|---|---|---|
| $factors | array; обязательный | Массив float; официальный текст описывает компоненты в RGB-порядке. Реальное отображение в JPEG проверяется по SOF. |
Официальная ошибка — GmagickException. Дополнительно PHP проверяет типы аргументов; прикладные ограничения пути и пресета в наших функциях дают InvalidArgumentException до вызова библиотеки. Не смешивайте эти уровни проверки.
Два самостоятельных применения: Сравнить реальные JPEG 4:4:4 и 4:2:2; Выбрать экспорт для цветной графики и веб-превью.
Отметка PHP.net: PECL gmagick >= Unknown. Unknown не сообщает известную минимальную версию. Наблюдения относятся к PHP 8.3.6/Gmagick 2.0.6RC1/GraphicsMagick 1.3.42 Q16; поведение экспортного кодера подтверждается реальными файлами.
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


