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

Дерево руководства
Глава 384 · После объектов, файлов и базовых цветовых пространств
Imagick: rendering intent, настоящее ICC-преобразование и экспорт sRGB
Не потерять смысл цвета: прочитать и задать режим, преобразовать корректный P3-вход в sRGB и проверить сохранение состояния в файле.
Получить настоящий sRGB-файл для каталога и увидеть частую ошибку
Сервис принимает изображение с телефона в Display P3 и должен отдать предсказуемый sRGB-файл для каталога. Если просто удалить ICC, те же числа каналов начинают интерпретироваться иначе: цвет кружки в нашем диагностическом просмотре тускнеет. Установка rendering intent сама не исправляет такую ошибку. Справа показан файл после настоящего преобразования с сохранённым целевым профилем.

Это собственный учебный рисунок, а не сторонняя фотография. Известный sRGB-исходник сначала действительно преобразован в DisplayP3Compat-v4; полученный source-p3.png содержит именно этот профиль. Мы не присваивали случайному sRGB-файлу ярлык P3. В архиве находятся оба исходника и два точных CC0-профиля. Исходный профилированный P3-файл может корректно выглядеть в умеющем управление цветом просмотрщике; ошибочная левая панель специально показывает потерю такой информации.
$image->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$intent = $image->getImageRenderingIntent();
$image->profileImage('icc', $srgb);$image — объект с изображением и верным встроенным P3-профилем; -> вызывает его метод. Imagick::RENDERINGINTENT_RELATIVE — именованная целочисленная константа, :: обращается к константе класса. Круглые скобки содержат аргументы; getter вызывается с пустыми скобками. $intent получает число, а не изменённую картинку. В третьей строке строка icc — имя типа профиля, $srgb — его бинарные байты, предварительно прочитанные file_get_contents. Именно profileImage выполняет последующую трансформацию; точка с запятой завершает каждую команду. Отдельная копия $export сохраняет настоящий PNG8: png:preserve-iCCP оставляет бинарный целевой профиль вместо замены метаданных, а повторное открытие $exported позволяет проверить фактически записанный файл. Объекты, переменные и чтение файлов разобраны отдельно.
Подготовить sRGB-превью из корректного P3-входа
Слева — ошибочный просмотр P3-чисел без исходного ICC, в центре — тот же результат после одного setter, справа — настоящий sRGB после profileImage. export-srgb.png сохраняет целевой ICC; диагностические PNG8 отдельно показывают разницу.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
$wrong=clone $input;
$wrong->removeImageProfile('icc');
$state=clone $wrong;
$set=$state->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$intent=$state->getImageRenderingIntent();
$converted=clone $input; // Keep the genuine embedded source ICC.
$converted->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$ok=$converted->profileImage('icc',$srgb);
$export=clone $converted;
$export->setImageFormat('png');$export->setImageDepth(8);
$export->setOption('png:bit-depth','8');$export->setOption('png:color-type','2');
$export->setOption('png:preserve-iCCP','true');
$export->writeImage(__DIR__.'/export-srgb.png');
$exported=new Imagick(__DIR__.'/export-srgb.png');
riFirstProof($input,$wrong,$state,$converted,$exported,$set,$ok,$intent,$before);
echo "rendering-intent-first.png\nsource-preview8.png\nwrong-stripped8.png\nsetter-only8.png\nconverted-srgb8.png\nexport-srgb.png\nmetrics.json\nset=true intent=4 setter-keeps-RGB=1 ICC-conversion=1\n";
Слева — ошибочный просмотр P3-чисел без исходного ICC, в центре — тот же результат после одного setter, справа — настоящий sRGB после profileImage. export-srgb.png сохраняет целевой ICC; диагностические PNG8 отдельно показывают разницу. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-first.png
source-preview8.png
wrong-stripped8.png
setter-only8.png
converted-srgb8.png
export-srgb.png
metrics.json
set=true intent=4 setter-keeps-RGB=1 ICC-conversion=1
Разделить числа RGB, исходный профиль, настройку и реальное преобразование

| Часть изображения | Что означает |
|---|---|
| RGB-пиксели | Числа каналов; без знания пространства недостаточны для однозначного смысла цвета. |
| Встроенный source ICC | Описывает, как интерпретировать существующие числа. Его нельзя угадывать по расширению файла. |
| Rendering intent | Настройка выбора способа отображения цветов при следующем управляемом преобразовании. |
| Целевой ICC и LCMS | profileImage использует их вместе с исходным профилем для вычисления новых чисел; целевой профиль связывается с результатом. |
| Getter | Читает текущее поле. Его число не доказывает, что предыдущий шаг был настоящей конверсией. |
Удобная модель — числа, их словарь значений и правило перевода. Аналогия ограничена: ICC не простая таблица названий цветов, а профиль с характеристиками каналов и преобразований. Setter выбирает правило, а не запускает перевод. Назначить другой словарь старым числам и вычислить соответствующие новые числа — разные действия. Если source ICC уже удалён, первый profileImage с sRGB лишь назначает его без преобразования: библиотеке неоткуда узнать прежний смысл P3-чисел.
Perceptual обычно выбирают для передачи общего впечатления с учётом гамута, Relative — для относительной колориметрии, Absolute — когда важна абсолютная колориметрия, Saturation — для соответствующей цели насыщенности. Конкретное отображение определяется профилями и CMS. Эти названия не гарантируют четыре визуально разных результата; наша пара matrix/TRC-профилей дала одинаковые RGB во всех проверенных режимах. Чёрная точка и её компенсация — отдельная настройка, setter intent её не включает. Не обещаем сохранение всех цветов при сужении гамута или неизбежную обратимость преобразования.
Назначение пространства и его преобразование также различаются: настройки colorspace помогают отделить метаданные от вычисления пикселей. Повторный export и композиция требуют учитывать, в каком пространстве уже находятся данные; одинаковое имя RGB ещё не означает одинаковый профиль.
Установить режим коротким вызовом и прочитать его после реального сохранения

Сначала короткая операция: вход уже содержит известный P3 ICC, clone создаёт отдельную рабочую копию. riRestore восстанавливает проверенные файлы из base64, riInput открывает source-p3.png. riHash измеряет численные RGB через PIXEL_DOUBLE, riICC считает SHA встроенного профиля; они не конвертируют цвет. После setter эти измерения должны остаться прежними.
Установить именованный режим и прочитать его без перекрашивания
Setter вернул true, getter — 4, то есть RENDERINGINTENT_RELATIVE в этой сборке. Числа RGB и байты встроенного ICC остались прежними; режим ещё не выполнил преобразование.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
$image=clone $input;
$ok=$image->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$intent=$image->getImageRenderingIntent();
riSetProof($input,$image,$ok,$intent,$before,$icc);
echo "rendering-intent-set.png\nset-before8.png\nmetrics.json\nset=true intent=4 RGB-unchanged=1 ICC-unchanged=1\n";
Setter вернул true, getter — 4, то есть RENDERINGINTENT_RELATIVE в этой сборке. Числа RGB и байты встроенного ICC остались прежними; режим ещё не выполнил преобразование. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-set.png
set-before8.png
metrics.json
set=true intent=4 RGB-unchanged=1 ICC-unchanged=1
$intent = $image->getImageRenderingIntent();
echo $intent;Это самый короткий смысл getter: прочитать int у уже существующего изображения. Теперь практическая причина действительно его прочитать — проверить состояние после сохранения и повторного открытия. В следующем примере до записи задан Relative=4. PNG с прежним ICC после декодирования вернул Perceptual=2, MIFF вернул 4; сравнение RGB и ICC при этом совпало. MIFF здесь контрольный собственный формат ImageMagick, не формат изображения для браузера. Его сохранение не является предложением отдавать MIFF пользователю сайта.
Прочитать режим после PNG и MIFF, сохранив проверку пикселей
Перед сохранением режим 4; после чтения PNG — 2, MIFF — 4. При этом измеренные RGB и встроенный ICC совпали. Getter отражает текущий объект после декодирования формата, а не обещает перенос произвольного поля через любой файл.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
$image=clone $input;
$image->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$beforeRead=$image->getImageRenderingIntent();
$savePNG=clone $image; $savePNG->setImageFormat('png');
$savePNG->writeImage(__DIR__.'/get-state.png');
$saveMIFF=clone $image; $saveMIFF->setImageFormat('miff');
$saveMIFF->writeImage(__DIR__.'/get-state.miff');
$png=new Imagick(__DIR__.'/get-state.png');
$miff=new Imagick(__DIR__.'/get-state.miff');
$pngRead=$png->getImageRenderingIntent();
$miffRead=$miff->getImageRenderingIntent();
riGetProof($input,$png,$miff,$beforeRead,$pngRead,$miffRead,$before,$icc);
echo "rendering-intent-get.png\nget-png8.png\nget-miff8.png\nget-state.png\nget-state.miff\nmetrics.json\nbefore=4 PNG=2 MIFF=4 RGB-same=1 ICC-same=1\n";
Перед сохранением режим 4; после чтения PNG — 2, MIFF — 4. При этом измеренные RGB и встроенный ICC совпали. Getter отражает текущий объект после декодирования формата, а не обещает перенос произвольного поля через любой файл. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-get.png
get-png8.png
get-miff8.png
get-state.png
get-state.miff
metrics.json
before=4 PNG=2 MIFF=4 RGB-same=1 ICC-same=1
get-state.png и get-state.miff — настоящие файлы сохранения. get-png8.png и get-miff8.png — отдельно изготовленные диагностические просмотры их чисел без ICC, оба подписаны как такие просмотры. Не нужно ждать разницы цветов от различного числа getter и нельзя считать эти PNG8 доказательством переноса режима. Вывод относится к проверенной сборке и точным файлам, а не ко всем PNG с любым набором chunks.
Собрать обработчик с реальной конверсией, политикой режима и понятными ошибками

В обработчике загрузки нужен предсказуемый вход: известный source ICC, явный режим, поддержка LCMS и отдельный выходной файл. chooseIntent ниже — собственная политика приложения, которая принимает четыре именованных режима. Мы намеренно показываем, что низкоуровневый setter допускает 999, поэтому его true не заменяет прикладную проверку. Контроль UNDEFINED в цикле нужен для изучения API; рабочая политика его не выбирает.
Выбрать режим, выполнить ICC-преобразование и не принять неправильный вход
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
function chooseIntent(int $intent):int {
$allowed=[Imagick::RENDERINGINTENT_PERCEPTUAL,Imagick::RENDERINGINTENT_RELATIVE,
Imagick::RENDERINGINTENT_SATURATION,Imagick::RENDERINGINTENT_ABSOLUTE];
if(!in_array($intent,$allowed,true)){throw new InvalidArgumentException('Choose one of the four supported application modes');}
return $intent;
}
$modes=['UNDEFINED'=>Imagick::RENDERINGINTENT_UNDEFINED,'PERCEPTUAL'=>Imagick::RENDERINGINTENT_PERCEPTUAL,
'RELATIVE'=>Imagick::RENDERINGINTENT_RELATIVE,'SATURATION'=>Imagick::RENDERINGINTENT_SATURATION,'ABSOLUTE'=>Imagick::RENDERINGINTENT_ABSOLUTE];
$cases=[];$outputs=[];
foreach($modes as $name=>$mode){
$image=clone $input;
$set=$image->setImageRenderingIntent($mode);$read=$image->getImageRenderingIntent();
$sameRGB=riHash($image)===$before;$sameICC=riICC($image)===$icc;
$ok=$image->profileImage('icc',$srgb);$outputs[$name]=$image;
$cases[$name]=['setter'=>$set,'getter'=>$read,'RGB_unchanged_after_set'=>$sameRGB,'ICC_unchanged_after_set'=>$sameICC,
'conversion_return'=>$ok,'converted_RGB_sha256'=>riHash($image),'converted_ICC_sha256'=>riICC($image),
'conversion_error'=>riError($input,$image),'roundtrip_error'=>riError(riOriginal(),$image)];
}
$invalid=clone $input;$invalidSet=$invalid->setImageRenderingIntent(999);$invalidRead=$invalid->getImageRenderingIntent();
$policyRejected=false;try{chooseIntent(999);}catch(InvalidArgumentException $error){$policyRejected=true;}
$chosen=chooseIntent(Imagick::RENDERINGINTENT_RELATIVE);
$untagged=clone $input;$untagged->removeImageProfile('icc');$unprofiledBefore=riHash($untagged);
$assigned=$untagged->profileImage('icc',$srgb);$assignmentOnly=riHash($untagged)===$unprofiledBefore;
$errors=[];
foreach(['get_empty'=>fn()=>(new Imagick())->getImageRenderingIntent(),
'set_empty'=>fn()=>(new Imagick())->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE),
'bad_icc'=>fn()=>(clone $input)->profileImage('icc','not an ICC profile')] as $name=>$operation){
try{$operation();$errors[$name]=['class'=>'not caught','message'=>''];}
catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
foreach(['PERCEPTUAL','RELATIVE','SATURATION','ABSOLUTE'] as $name){riView($outputs[$name],'workflow-'.strtolower($name).'8.png');}
riView($untagged,'workflow-wrong-assigned8.png');
$rects=riCompare([$outputs['PERCEPTUAL'],$outputs['RELATIVE'],$outputs['SATURATION']],'rendering-intent-workflow.png');
$hashes=array_column($cases,'converted_RGB_sha256');$allEqual=count(array_unique($hashes))===1;
$allValid=true;foreach($cases as $name=>$case){$allValid=$allValid&&$case['setter']===true&&$case['getter']===$modes[$name]
&&$case['RGB_unchanged_after_set']&&$case['ICC_unchanged_after_set']&&$case['conversion_return']===true
&&$case['converted_ICC_sha256']===hash('sha256',$srgb)&&$case['conversion_error']['max']===51&&$case['roundtrip_error']['max']===5;}
riDiagnostic('rendering-intent-workflow',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],'cases'=>$cases,
'all_converted_RGB_equal'=>$allEqual,'invalid_integer'=>['setter'=>$invalidSet,'getter'=>$invalidRead,'RGB_unchanged'=>riHash($invalid)===$before],
'policy_rejects_999'=>$policyRejected,'chosen_policy_intent'=>$chosen,'missing_source_profile'=>['assignment_return'=>$assigned,'RGB_unchanged'=>$assignmentOnly],
'errors'=>$errors,'source_unchanged'=>riHash($input)===$before,'panel_geometry'=>$rects,
'checks'=>['five_modes_executed'=>$allValid,'same_real_result_for_this_profile_pair'=>$allEqual,
'setter_accepts_invalid_integer'=>$invalidSet===true&&$invalidRead===999&&riHash($invalid)===$before,
'application_policy_rejects_999'=>$policyRejected,'missing_source_does_not_convert'=>$assigned===true&&$assignmentOnly,
'three_errors_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
'original_preserved'=>riHash($input)===$before]]);
echo "rendering-intent-workflow.png\nworkflow-perceptual8.png\nworkflow-relative8.png\nworkflow-saturation8.png\nworkflow-absolute8.png\nworkflow-wrong-assigned8.png\nmetrics.json\nmodes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3\n";
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-workflow.png
workflow-perceptual8.png
workflow-relative8.png
workflow-saturation8.png
workflow-absolute8.png
workflow-wrong-assigned8.png
metrics.json
modes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3
Все пять реальных преобразований дали одинаковый RGB-хэш для этой пары профилей. От P3-входа изменились 65 514 из 384 000 компонентов каналов, максимальная разница 51, RMSE 6.844484359; это изменение чисел при переводе между пространствами, не измерение визуального улучшения. С известным исходным sRGB после кругового преобразования получены max 5 и RMSE 0.389296909. Эти RGB через PIXEL_CHAR измерены до отдельного кодирования просмотров PNG8; значения не приравниваются к заново декодированным PNG8 без проверки округления. Хэши неизменности используют PIXEL_DOUBLE. Маленькая ошибка этой конкретной RGB-пары не обещает такой же результат для CMYK, другого гамута, JPEG или другой CMS.
| Ситуация | Что фактически произошло |
|---|---|
| 999 передано напрямую setter | true, getter=999, RGB прежние; chooseIntent отдельно отклонил это значение. |
| Удалён исходный ICC, затем назначен sRGB | profileImage вернул true, но численные RGB не изменились. Это назначение, не восстановление утраченного смысла исходного цвета. |
| Getter или setter на пустом Imagick | ImagickException: Can not process empty Imagick object. |
| Строка not an ICC profile вместо бинарного ICC | ImagickException: ColorspaceColorProfileMismatch. Полное сообщение сохранено в metrics.json. |
Лицензия CC0 и provenance включены в каждый архив. Выбраны DisplayP3Compat-v4 и sRGB-v4 из Compact-ICC-Profiles, commit bdd84663061bc4ae95ca70decff54f581e27f702. Это не проприетарные Windows-профили и не обещание побитового совпадения с Apple Display P3. README отдельно предупреждает про отрицательный Z в Max-Correctness варианте; Compat рассчитан на совместимость.
Сохранить полный официальный контракт и воспроизвести запуск
Полный официальный базис
Imagick::getImageRenderingIntent(): intОфициальная доступность: PECL imagick 2 и 3; оба метода существуют в проверенной Imagick 3.8.1 с IM7 и не объявлены здесь устаревшими. Полная исходная запись с описанием, параметрами, результатом и исключениями сохранена ниже; официальных примеров на этих двух страницах нет.
getImageRenderingIntent не принимает аргументов и возвращает int — текущий rendering intent изображения. Это значение настройки, не изображение, не профиль и не признак успешного ICC-преобразования. Возможен RENDERINGINTENT_UNDEFINED. После чтения файла значение зависит также от декодера и формата; наш PNG вернул 2, хотя перед сохранением поле было 4, а MIFF сохранил 4.
Именованные значения этой сборки: UNDEFINED=0, SATURATION=1, PERCEPTUAL=2, ABSOLUTE=3, RELATIVE=4. Это enum Imagick, не нумерация rendering intent в бинарном заголовке ICC. Переносимый код использует имена констант. Для реального profileImage-преобразования текущий Core передаёт выбранный режим LCMS; Undefined и неизвестные значения в этой конкретной ветке переходят к Perceptual. Это поведение реализации, а не рекомендация пропускать проверку входа.
Официальный раздел ошибок указывает ImagickException. Оба метода требуют непустого текущего изображения; в реальном запуске пустой объект дал Can not process empty Imagick object. Отдельные ошибки чтения ICC или создания цветовой трансформации относятся к profileImage, а не к getter. В рабочем сценарии заранее проверяют наличие правильного исходного профиля, выбирают разрешённый intent и сохраняют целевой профиль вместе с преобразованными пикселями.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagerenderingintent">
<refnamediv>
<refname>Imagick::getImageRenderingIntent</refname>
<refpurpose>Gets the image rendering intent</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>int</type><methodname>Imagick::getImageRenderingIntent</methodname>
<void/>
</methodsynopsis>
<para>
Gets the image rendering intent.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns the image <link
linkend="imagick.constants.renderingintent">rendering intent</link>.
</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
-->
Полный официальный базис
Imagick::setImageRenderingIntent(int $rendering_intent): boolОфициальная доступность: PECL imagick 2 и 3; оба метода существуют в проверенной Imagick 3.8.1 с IM7 и не объявлены здесь устаревшими. Полная исходная запись с описанием, параметрами, результатом и исключениями сохранена ниже; официальных примеров на этих двух страницах нет.
setImageRenderingIntent принимает обязательный int $rendering_intent и возвращает true при успехе. Используйте именованные константы, выбирая политику предстоящего цветового преобразования. Сам setter меняет поле текущего изображения, не преобразует RGB и не переписывает байты существующего ICC. В этой реализации число 999 тоже сохраняется — return=true не является проверкой допустимого режима.
Именованные значения этой сборки: UNDEFINED=0, SATURATION=1, PERCEPTUAL=2, ABSOLUTE=3, RELATIVE=4. Это enum Imagick, не нумерация rendering intent в бинарном заголовке ICC. Переносимый код использует имена констант. Для реального profileImage-преобразования текущий Core передаёт выбранный режим LCMS; Undefined и неизвестные значения в этой конкретной ветке переходят к Perceptual. Это поведение реализации, а не рекомендация пропускать проверку входа.
Официальный раздел ошибок указывает ImagickException. Оба метода требуют непустого текущего изображения; в реальном запуске пустой объект дал Can not process empty Imagick object. Отдельные ошибки чтения ICC или создания цветовой трансформации относятся к profileImage, а не к getter. В рабочем сценарии заранее проверяют наличие правильного исходного профиля, выбирают разрешённый intent и сохраняют целевой профиль вместе с преобразованными пикселями.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagerenderingintent">
<refnamediv>
<refname>Imagick::setImageRenderingIntent</refname>
<refpurpose>Sets the image rendering intent</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageRenderingIntent</methodname>
<methodparam><type>int</type><parameter>rendering_intent</parameter></methodparam>
</methodsynopsis>
<para>
Sets the image rendering intent.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>rendering_intent</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
&imagick.imagick.throws;
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Для запуска нужны PHP CLI, расширение Imagick, связанный ImageMagick с LCMS и поддержкой используемых PNG/MIFF. В нашем запуске библиотека реально выполнила преобразование: одно наличие методов или return=true этого не доказывает. Файлы примера локальны, внешние сервисы не вызываются. PNG для HTTP отправляют отдельным ответом с Content-Type: image/png; диагностический текст не смешивают с бинарным телом.
Весь исполняемый fixture, отдельно от коротких вызовов
<?php
declare(strict_types=1);
function riRestore():void {
$hashes=['source.png'=>'f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c','source-p3.png'=>'8d17f52b840975ce18149cd08ceb0c488dc29878cb61ed8eb2ebb99b8e488eb1','source-p3.icc'=>'231752984cd4a5278e1b8d2390fe496767d4511fc81f54e1a5c69ae9ab4c42b5','target-srgb.icc'=>'c56e1685d888f5edb92fe07f2750f387f8fe8e91b32ff8fb0b56bfbbb9458353'];
foreach($hashes as $name=>$hash){
$raw=base64_decode((string)file_get_contents(__DIR__.'/'.$name.'.b64'),true);
if($raw===false||hash('sha256',$raw)!==$hash||file_put_contents(__DIR__.'/'.$name,$raw)===false){throw new RuntimeException('Known image or ICC fixture missing/changed: '.$name);}
}
}
function riInput():Imagick {return new Imagick(__DIR__.'/source-p3.png');}
function riOriginal():Imagick {
$input=new Imagick(__DIR__.'/source.png');$base=new Imagick();$base->newImage(400,320,'white','png');
$base->compositeImage($input,Imagick::COMPOSITE_OVER,0,0);$base->setImageAlphaChannel(Imagick::ALPHACHANNEL_OFF);return $base;
}
function riHash(Imagick $image):string {return hash('sha256',json_encode($image->exportImagePixels(0,0,400,320,'RGB',Imagick::PIXEL_DOUBLE),JSON_THROW_ON_ERROR));}
function riICC(Imagick $image):string {return hash('sha256',$image->getImageProfile('icc'));}
function riError(Imagick $a,Imagick $b):array {
$x=$a->exportImagePixels(0,0,400,320,'RGB',Imagick::PIXEL_CHAR);$y=$b->exportImagePixels(0,0,400,320,'RGB',Imagick::PIXEL_CHAR);
$max=0;$sum=0;$changed=0;foreach($x as $i=>$v){$d=abs($v-$y[$i]);$max=max($max,$d);$sum+=$d*$d;$changed+=(int)($d!==0);}
return ['max'=>$max,'RMSE'=>sqrt($sum/count($x)),'changed_components'=>$changed,'components'=>count($x)];
}
function riView(Imagick $image,string $name):void {
// This deliberately unmanaged PNG8 is a diagnostic view, not an ICC transform.
$copy=clone $image;$copy->stripImage();$copy->setImageFormat('png');$copy->setImageDepth(8);
$copy->setOption('png:bit-depth','8');$copy->setOption('png:color-type','2');$copy->setOption('png:exclude-chunk','all');
if(!$copy->writeImage(__DIR__.'/'.$name)){throw new RuntimeException('Cannot write display PNG');}
}
function riCompare(array $images,string $name):array {
$board=new Imagick();$board->newImage(400*count($images),320,'white');$rects=[];
foreach($images as $i=>$image){
if($image->getImageWidth()!==400||$image->getImageHeight()!==320){throw new RuntimeException('Expected 400x320 panel');}
$raw=clone $image;$raw->stripImage();$board->compositeImage($raw,Imagick::COMPOSITE_OVER,400*$i,0);
$rects[]=['x'=>400*$i,'y'=>0,'width'=>400,'height'=>320];
}
riView($board,$name);return $rects;
}
function riDiagnostic(string $id,array $data):void {
$doc=['schema'=>'aen-rendering-intent-program-diagnostics-v1','example_id'=>$id,'runtime'=>['php'=>PHP_VERSION,'imagick'=>phpversion('imagick'),'image_magick'=>Imagick::getVersion()]]+$data;
if(file_put_contents(__DIR__.'/metrics.json',json_encode($doc,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)."\n")===false){throw new RuntimeException('Diagnostic write failed');}
}
function riFirstProof(Imagick $input,Imagick $wrong,Imagick $state,Imagick $converted,Imagick $exported,bool $set,bool $ok,int $intent,string $before):void {
$change=riError($input,$converted);$roundtrip=riError(riOriginal(),$converted);
riView(riOriginal(),'source-preview8.png');riView($wrong,'wrong-stripped8.png');riView($state,'setter-only8.png');riView($converted,'converted-srgb8.png');
$rects=riCompare([$wrong,$state,$converted],'rendering-intent-first.png');
riDiagnostic('rendering-intent-first',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],'setter_return'=>$set,'getter'=>$intent,
'conversion_return'=>$ok,'setter_RGB_unchanged'=>riHash($wrong)===riHash($state),'conversion_error'=>$change,'roundtrip_error'=>$roundtrip,
'target_ICC_sha256'=>riICC($converted),'export_ICC_sha256'=>riICC($exported),'export_RGB_error'=>riError($converted,$exported),'source_unchanged'=>riHash($input)===$before,'panel_geometry'=>$rects,
'checks'=>['setter_true'=>$set===true,'getter_relative'=>$intent===Imagick::RENDERINGINTENT_RELATIVE,'setter_keeps_RGB'=>riHash($wrong)===riHash($state),
'real_conversion'=>$ok===true&&$change['max']===51&&$change['changed_components']===65514,'target_ICC'=>riICC($converted)==='c56e1685d888f5edb92fe07f2750f387f8fe8e91b32ff8fb0b56bfbbb9458353',
'bounded_roundtrip'=>$roundtrip['max']===5,'production_ICC_preserved'=>riICC($exported)==='c56e1685d888f5edb92fe07f2750f387f8fe8e91b32ff8fb0b56bfbbb9458353','production_quantization_bounded'=>riError($converted,$exported)['max']<=1,'source_preserved'=>riHash($input)===$before]]);
}
function riSetProof(Imagick $input,Imagick $image,bool $ok,int $intent,string $before,string $icc):void {
riView($input,'set-before8.png');riView($image,'rendering-intent-set.png');
riDiagnostic('rendering-intent-set-minimal',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],'setter_return'=>$ok,'getter'=>$intent,
'RGB_unchanged_after_set'=>riHash($image)===$before,'ICC_unchanged_after_set'=>riICC($image)===$icc,'source_unchanged'=>riHash($input)===$before,
'checks'=>['setter_true'=>$ok===true,'named_mode_read'=>$intent===Imagick::RENDERINGINTENT_RELATIVE,'RGB_unchanged'=>riHash($image)===$before,
'ICC_unchanged'=>riICC($image)===$icc,'source_preserved'=>riHash($input)===$before]]);
}
function riGetProof(Imagick $input,Imagick $png,Imagick $miff,int $beforeRead,int $pngRead,int $miffRead,string $before,string $icc):void {
riView($png,'get-png8.png');riView($miff,'get-miff8.png');$rects=riCompare([$png,$miff],'rendering-intent-get.png');
riDiagnostic('rendering-intent-get-minimal',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],
'before_save'=>$beforeRead,'png_getter'=>$pngRead,'miff_getter'=>$miffRead,'png_RGB_error'=>riError($input,$png),'miff_RGB_error'=>riError($input,$miff),
'png_ICC_sha256'=>riICC($png),'miff_ICC_sha256'=>riICC($miff),'source_unchanged'=>riHash($input)===$before,'panel_geometry'=>$rects,
'checks'=>['before_relative'=>$beforeRead===Imagick::RENDERINGINTENT_RELATIVE,'png_actual_perceptual'=>$pngRead===Imagick::RENDERINGINTENT_PERCEPTUAL,
'miff_preserves_relative'=>$miffRead===Imagick::RENDERINGINTENT_RELATIVE,'png_RGB_preserved'=>riError($input,$png)['max']===0,
'miff_RGB_preserved'=>riError($input,$miff)['max']===0,'ICCs_preserved'=>riICC($png)===$icc&&riICC($miff)===$icc,'source_preserved'=>riHash($input)===$before]]);
}
riRestore проверяет четыре точных входа по SHA; riOriginal создаёт белую непрозрачную основу исходного собственного PNG, а riView удаляет метаданные только у отдельной диагностической копии и сохраняет PNG8. riCompare собирает натуральные панели 400 × 320 без масштабирования. riError сравнивает численные RGB, riDiagnostic записывает измерения; ни один helper не подменяет изучаемые вызовы setter/getter. Упражнение: замените рабочую политику Relative на Perceptual и объясните, почему равенство результата для этих профилей не делает режимы универсально одинаковыми. Решение: setter сохранит другое поле, profileImage передаст другой intent CMS, но выбранные профили вправе дать те же числа. Следующий шаг — обработка ошибок, собственные функции и различие назначения и преобразования пространства.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::getImageRenderingIntentПрочитать или выбрать режим перед настоящим ICC-преобразованием, различать поле и цвет пикселей
PECL imagick 2, PECL imagick 3 · imagick
Imagick::getImageRenderingIntent(): intПолный официальный базис
Imagick::getImageRenderingIntent(): intОфициальная доступность: PECL imagick 2 и 3; оба метода существуют в проверенной Imagick 3.8.1 с IM7 и не объявлены здесь устаревшими. Полная исходная запись с описанием, параметрами, результатом и исключениями сохранена ниже; официальных примеров на этих двух страницах нет.
getImageRenderingIntent не принимает аргументов и возвращает int — текущий rendering intent изображения. Это значение настройки, не изображение, не профиль и не признак успешного ICC-преобразования. Возможен RENDERINGINTENT_UNDEFINED. После чтения файла значение зависит также от декодера и формата; наш PNG вернул 2, хотя перед сохранением поле было 4, а MIFF сохранил 4.
Именованные значения этой сборки: UNDEFINED=0, SATURATION=1, PERCEPTUAL=2, ABSOLUTE=3, RELATIVE=4. Это enum Imagick, не нумерация rendering intent в бинарном заголовке ICC. Переносимый код использует имена констант. Для реального profileImage-преобразования текущий Core передаёт выбранный режим LCMS; Undefined и неизвестные значения в этой конкретной ветке переходят к Perceptual. Это поведение реализации, а не рекомендация пропускать проверку входа.
Официальный раздел ошибок указывает ImagickException. Оба метода требуют непустого текущего изображения; в реальном запуске пустой объект дал Can not process empty Imagick object. Отдельные ошибки чтения ICC или создания цветовой трансформации относятся к profileImage, а не к getter. В рабочем сценарии заранее проверяют наличие правильного исходного профиля, выбирают разрешённый intent и сохраняют целевой профиль вместе с преобразованными пикселями.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagerenderingintent">
<refnamediv>
<refname>Imagick::getImageRenderingIntent</refname>
<refpurpose>Gets the image rendering intent</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>int</type><methodname>Imagick::getImageRenderingIntent</methodname>
<void/>
</methodsynopsis>
<para>
Gets the image rendering intent.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns the image <link
linkend="imagick.constants.renderingintent">rendering intent</link>.
</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
-->
Прочитать режим после PNG и MIFF, сохранив проверку пикселей
Перед сохранением режим 4; после чтения PNG — 2, MIFF — 4. При этом измеренные RGB и встроенный ICC совпали. Getter отражает текущий объект после декодирования формата, а не обещает перенос произвольного поля через любой файл.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
$image=clone $input;
$image->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$beforeRead=$image->getImageRenderingIntent();
$savePNG=clone $image; $savePNG->setImageFormat('png');
$savePNG->writeImage(__DIR__.'/get-state.png');
$saveMIFF=clone $image; $saveMIFF->setImageFormat('miff');
$saveMIFF->writeImage(__DIR__.'/get-state.miff');
$png=new Imagick(__DIR__.'/get-state.png');
$miff=new Imagick(__DIR__.'/get-state.miff');
$pngRead=$png->getImageRenderingIntent();
$miffRead=$miff->getImageRenderingIntent();
riGetProof($input,$png,$miff,$beforeRead,$pngRead,$miffRead,$before,$icc);
echo "rendering-intent-get.png\nget-png8.png\nget-miff8.png\nget-state.png\nget-state.miff\nmetrics.json\nbefore=4 PNG=2 MIFF=4 RGB-same=1 ICC-same=1\n";
Перед сохранением режим 4; после чтения PNG — 2, MIFF — 4. При этом измеренные RGB и встроенный ICC совпали. Getter отражает текущий объект после декодирования формата, а не обещает перенос произвольного поля через любой файл. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-get.png
get-png8.png
get-miff8.png
get-state.png
get-state.miff
metrics.json
before=4 PNG=2 MIFF=4 RGB-same=1 ICC-same=1
Выбрать режим, выполнить ICC-преобразование и не принять неправильный вход
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
function chooseIntent(int $intent):int {
$allowed=[Imagick::RENDERINGINTENT_PERCEPTUAL,Imagick::RENDERINGINTENT_RELATIVE,
Imagick::RENDERINGINTENT_SATURATION,Imagick::RENDERINGINTENT_ABSOLUTE];
if(!in_array($intent,$allowed,true)){throw new InvalidArgumentException('Choose one of the four supported application modes');}
return $intent;
}
$modes=['UNDEFINED'=>Imagick::RENDERINGINTENT_UNDEFINED,'PERCEPTUAL'=>Imagick::RENDERINGINTENT_PERCEPTUAL,
'RELATIVE'=>Imagick::RENDERINGINTENT_RELATIVE,'SATURATION'=>Imagick::RENDERINGINTENT_SATURATION,'ABSOLUTE'=>Imagick::RENDERINGINTENT_ABSOLUTE];
$cases=[];$outputs=[];
foreach($modes as $name=>$mode){
$image=clone $input;
$set=$image->setImageRenderingIntent($mode);$read=$image->getImageRenderingIntent();
$sameRGB=riHash($image)===$before;$sameICC=riICC($image)===$icc;
$ok=$image->profileImage('icc',$srgb);$outputs[$name]=$image;
$cases[$name]=['setter'=>$set,'getter'=>$read,'RGB_unchanged_after_set'=>$sameRGB,'ICC_unchanged_after_set'=>$sameICC,
'conversion_return'=>$ok,'converted_RGB_sha256'=>riHash($image),'converted_ICC_sha256'=>riICC($image),
'conversion_error'=>riError($input,$image),'roundtrip_error'=>riError(riOriginal(),$image)];
}
$invalid=clone $input;$invalidSet=$invalid->setImageRenderingIntent(999);$invalidRead=$invalid->getImageRenderingIntent();
$policyRejected=false;try{chooseIntent(999);}catch(InvalidArgumentException $error){$policyRejected=true;}
$chosen=chooseIntent(Imagick::RENDERINGINTENT_RELATIVE);
$untagged=clone $input;$untagged->removeImageProfile('icc');$unprofiledBefore=riHash($untagged);
$assigned=$untagged->profileImage('icc',$srgb);$assignmentOnly=riHash($untagged)===$unprofiledBefore;
$errors=[];
foreach(['get_empty'=>fn()=>(new Imagick())->getImageRenderingIntent(),
'set_empty'=>fn()=>(new Imagick())->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE),
'bad_icc'=>fn()=>(clone $input)->profileImage('icc','not an ICC profile')] as $name=>$operation){
try{$operation();$errors[$name]=['class'=>'not caught','message'=>''];}
catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
foreach(['PERCEPTUAL','RELATIVE','SATURATION','ABSOLUTE'] as $name){riView($outputs[$name],'workflow-'.strtolower($name).'8.png');}
riView($untagged,'workflow-wrong-assigned8.png');
$rects=riCompare([$outputs['PERCEPTUAL'],$outputs['RELATIVE'],$outputs['SATURATION']],'rendering-intent-workflow.png');
$hashes=array_column($cases,'converted_RGB_sha256');$allEqual=count(array_unique($hashes))===1;
$allValid=true;foreach($cases as $name=>$case){$allValid=$allValid&&$case['setter']===true&&$case['getter']===$modes[$name]
&&$case['RGB_unchanged_after_set']&&$case['ICC_unchanged_after_set']&&$case['conversion_return']===true
&&$case['converted_ICC_sha256']===hash('sha256',$srgb)&&$case['conversion_error']['max']===51&&$case['roundtrip_error']['max']===5;}
riDiagnostic('rendering-intent-workflow',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],'cases'=>$cases,
'all_converted_RGB_equal'=>$allEqual,'invalid_integer'=>['setter'=>$invalidSet,'getter'=>$invalidRead,'RGB_unchanged'=>riHash($invalid)===$before],
'policy_rejects_999'=>$policyRejected,'chosen_policy_intent'=>$chosen,'missing_source_profile'=>['assignment_return'=>$assigned,'RGB_unchanged'=>$assignmentOnly],
'errors'=>$errors,'source_unchanged'=>riHash($input)===$before,'panel_geometry'=>$rects,
'checks'=>['five_modes_executed'=>$allValid,'same_real_result_for_this_profile_pair'=>$allEqual,
'setter_accepts_invalid_integer'=>$invalidSet===true&&$invalidRead===999&&riHash($invalid)===$before,
'application_policy_rejects_999'=>$policyRejected,'missing_source_does_not_convert'=>$assigned===true&&$assignmentOnly,
'three_errors_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
'original_preserved'=>riHash($input)===$before]]);
echo "rendering-intent-workflow.png\nworkflow-perceptual8.png\nworkflow-relative8.png\nworkflow-saturation8.png\nworkflow-absolute8.png\nworkflow-wrong-assigned8.png\nmetrics.json\nmodes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3\n";
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-workflow.png
workflow-perceptual8.png
workflow-relative8.png
workflow-saturation8.png
workflow-absolute8.png
workflow-wrong-assigned8.png
metrics.json
modes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3
Imagick::setImageRenderingIntentПрочитать или выбрать режим перед настоящим ICC-преобразованием, различать поле и цвет пикселей
PECL imagick 2, PECL imagick 3 · imagick
Imagick::setImageRenderingIntent(int $rendering_intent): boolПолный официальный базис
Imagick::setImageRenderingIntent(int $rendering_intent): boolОфициальная доступность: PECL imagick 2 и 3; оба метода существуют в проверенной Imagick 3.8.1 с IM7 и не объявлены здесь устаревшими. Полная исходная запись с описанием, параметрами, результатом и исключениями сохранена ниже; официальных примеров на этих двух страницах нет.
setImageRenderingIntent принимает обязательный int $rendering_intent и возвращает true при успехе. Используйте именованные константы, выбирая политику предстоящего цветового преобразования. Сам setter меняет поле текущего изображения, не преобразует RGB и не переписывает байты существующего ICC. В этой реализации число 999 тоже сохраняется — return=true не является проверкой допустимого режима.
Именованные значения этой сборки: UNDEFINED=0, SATURATION=1, PERCEPTUAL=2, ABSOLUTE=3, RELATIVE=4. Это enum Imagick, не нумерация rendering intent в бинарном заголовке ICC. Переносимый код использует имена констант. Для реального profileImage-преобразования текущий Core передаёт выбранный режим LCMS; Undefined и неизвестные значения в этой конкретной ветке переходят к Perceptual. Это поведение реализации, а не рекомендация пропускать проверку входа.
Официальный раздел ошибок указывает ImagickException. Оба метода требуют непустого текущего изображения; в реальном запуске пустой объект дал Can not process empty Imagick object. Отдельные ошибки чтения ICC или создания цветовой трансформации относятся к profileImage, а не к getter. В рабочем сценарии заранее проверяют наличие правильного исходного профиля, выбирают разрешённый intent и сохраняют целевой профиль вместе с преобразованными пикселями.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagerenderingintent">
<refnamediv>
<refname>Imagick::setImageRenderingIntent</refname>
<refpurpose>Sets the image rendering intent</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageRenderingIntent</methodname>
<methodparam><type>int</type><parameter>rendering_intent</parameter></methodparam>
</methodsynopsis>
<para>
Sets the image rendering intent.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>rendering_intent</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
&imagick.imagick.throws;
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Установить именованный режим и прочитать его без перекрашивания
Setter вернул true, getter — 4, то есть RENDERINGINTENT_RELATIVE в этой сборке. Числа RGB и байты встроенного ICC остались прежними; режим ещё не выполнил преобразование.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
$image=clone $input;
$ok=$image->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE);
$intent=$image->getImageRenderingIntent();
riSetProof($input,$image,$ok,$intent,$before,$icc);
echo "rendering-intent-set.png\nset-before8.png\nmetrics.json\nset=true intent=4 RGB-unchanged=1 ICC-unchanged=1\n";
Setter вернул true, getter — 4, то есть RENDERINGINTENT_RELATIVE в этой сборке. Числа RGB и байты встроенного ICC остались прежними; режим ещё не выполнил преобразование. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-set.png
set-before8.png
metrics.json
set=true intent=4 RGB-unchanged=1 ICC-unchanged=1
Выбрать режим, выполнить ICC-преобразование и не принять неправильный вход
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены.
<?php
declare(strict_types=1);
require __DIR__.'/rendering-intent-fixture.php';
riRestore();
$input=riInput(); $before=riHash($input);
$icc=riICC($input); $srgb=file_get_contents(__DIR__.'/target-srgb.icc');
function chooseIntent(int $intent):int {
$allowed=[Imagick::RENDERINGINTENT_PERCEPTUAL,Imagick::RENDERINGINTENT_RELATIVE,
Imagick::RENDERINGINTENT_SATURATION,Imagick::RENDERINGINTENT_ABSOLUTE];
if(!in_array($intent,$allowed,true)){throw new InvalidArgumentException('Choose one of the four supported application modes');}
return $intent;
}
$modes=['UNDEFINED'=>Imagick::RENDERINGINTENT_UNDEFINED,'PERCEPTUAL'=>Imagick::RENDERINGINTENT_PERCEPTUAL,
'RELATIVE'=>Imagick::RENDERINGINTENT_RELATIVE,'SATURATION'=>Imagick::RENDERINGINTENT_SATURATION,'ABSOLUTE'=>Imagick::RENDERINGINTENT_ABSOLUTE];
$cases=[];$outputs=[];
foreach($modes as $name=>$mode){
$image=clone $input;
$set=$image->setImageRenderingIntent($mode);$read=$image->getImageRenderingIntent();
$sameRGB=riHash($image)===$before;$sameICC=riICC($image)===$icc;
$ok=$image->profileImage('icc',$srgb);$outputs[$name]=$image;
$cases[$name]=['setter'=>$set,'getter'=>$read,'RGB_unchanged_after_set'=>$sameRGB,'ICC_unchanged_after_set'=>$sameICC,
'conversion_return'=>$ok,'converted_RGB_sha256'=>riHash($image),'converted_ICC_sha256'=>riICC($image),
'conversion_error'=>riError($input,$image),'roundtrip_error'=>riError(riOriginal(),$image)];
}
$invalid=clone $input;$invalidSet=$invalid->setImageRenderingIntent(999);$invalidRead=$invalid->getImageRenderingIntent();
$policyRejected=false;try{chooseIntent(999);}catch(InvalidArgumentException $error){$policyRejected=true;}
$chosen=chooseIntent(Imagick::RENDERINGINTENT_RELATIVE);
$untagged=clone $input;$untagged->removeImageProfile('icc');$unprofiledBefore=riHash($untagged);
$assigned=$untagged->profileImage('icc',$srgb);$assignmentOnly=riHash($untagged)===$unprofiledBefore;
$errors=[];
foreach(['get_empty'=>fn()=>(new Imagick())->getImageRenderingIntent(),
'set_empty'=>fn()=>(new Imagick())->setImageRenderingIntent(Imagick::RENDERINGINTENT_RELATIVE),
'bad_icc'=>fn()=>(clone $input)->profileImage('icc','not an ICC profile')] as $name=>$operation){
try{$operation();$errors[$name]=['class'=>'not caught','message'=>''];}
catch(Throwable $error){$errors[$name]=['class'=>get_class($error),'message'=>$error->getMessage()];}
}
foreach(['PERCEPTUAL','RELATIVE','SATURATION','ABSOLUTE'] as $name){riView($outputs[$name],'workflow-'.strtolower($name).'8.png');}
riView($untagged,'workflow-wrong-assigned8.png');
$rects=riCompare([$outputs['PERCEPTUAL'],$outputs['RELATIVE'],$outputs['SATURATION']],'rendering-intent-workflow.png');
$hashes=array_column($cases,'converted_RGB_sha256');$allEqual=count(array_unique($hashes))===1;
$allValid=true;foreach($cases as $name=>$case){$allValid=$allValid&&$case['setter']===true&&$case['getter']===$modes[$name]
&&$case['RGB_unchanged_after_set']&&$case['ICC_unchanged_after_set']&&$case['conversion_return']===true
&&$case['converted_ICC_sha256']===hash('sha256',$srgb)&&$case['conversion_error']['max']===51&&$case['roundtrip_error']['max']===5;}
riDiagnostic('rendering-intent-workflow',['executed_apis'=>['setImageRenderingIntent','getImageRenderingIntent'],'cases'=>$cases,
'all_converted_RGB_equal'=>$allEqual,'invalid_integer'=>['setter'=>$invalidSet,'getter'=>$invalidRead,'RGB_unchanged'=>riHash($invalid)===$before],
'policy_rejects_999'=>$policyRejected,'chosen_policy_intent'=>$chosen,'missing_source_profile'=>['assignment_return'=>$assigned,'RGB_unchanged'=>$assignmentOnly],
'errors'=>$errors,'source_unchanged'=>riHash($input)===$before,'panel_geometry'=>$rects,
'checks'=>['five_modes_executed'=>$allValid,'same_real_result_for_this_profile_pair'=>$allEqual,
'setter_accepts_invalid_integer'=>$invalidSet===true&&$invalidRead===999&&riHash($invalid)===$before,
'application_policy_rejects_999'=>$policyRejected,'missing_source_does_not_convert'=>$assigned===true&&$assignmentOnly,
'three_errors_caught'=>array_column($errors,'class')===['ImagickException','ImagickException','ImagickException'],
'original_preserved'=>riHash($input)===$before]]);
echo "rendering-intent-workflow.png\nworkflow-perceptual8.png\nworkflow-relative8.png\nworkflow-saturation8.png\nworkflow-absolute8.png\nworkflow-wrong-assigned8.png\nmetrics.json\nmodes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3\n";
Для этой пары matrix/TRC-профилей пять проверенных режимов дали одинаковый реальный RGB-результат. Произвольное 999 API принимает, но явная политика приложения отклоняет. На входе без исходного ICC новый sRGB только назначился; три намеренные ошибки перехвачены. Самостоятельный архив содержит четыре base64-входа: собственный исходный PNG, полученный настоящим преобразованием P3 PNG и два ICC; рядом лежат rendering-intent-fixture.php и исходная CC0-лицензия. Распакуйте в отдельный каталог и выполните php example.php. Проверено: PHP 8.5.11 / Imagick 3.8.1 / ImageMagick 7.1.1-46 Q16 без HDRI, с LCMS, PNG и MIFF. riRestore декодирует точные входные байты и проверяет SHA. Вызовы изучаемых методов видны в основной программе; helper только готовит вход, записывает диагностические просмотры и измерения. Просмотры riView намеренно удаляют профили на копии: они не являются скрытым ICC-преобразованием и не выдаются за правильное отображение P3.
Ожидаемый вывод в проверенной сборке
rendering-intent-workflow.png
workflow-perceptual8.png
workflow-relative8.png
workflow-saturation8.png
workflow-absolute8.png
workflow-wrong-assigned8.png
metrics.json
modes=5 converted-RGB-equal=1 API-accepts-999=1 policy-rejects-999=1 errors=3
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


