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

Дерево руководства
Глава 379 · После объектов, файлов, клонирования и каналов
Imagick: вращательное размытие и чёткое окно на фоне
Увидеть настоящий круговой смаз 8° и 20°, собрать фон с чётким центральным фрагментом и заменить историческое radialBlurImage.
Получить видимое круговое размытие и сравнить углы
Для промо-блока нужен фон с ощущением кругового движения, а главный фрагмент товара должен остаться чётким. Сначала посмотрим, что делает сама операция: рядом будут исходная иллюстрация и две её копии после 8° и 20°. Затем соберём шаблон с размытым фоном и чётким центральным окном. Это оформление, которое можно сохранить как обычный PNG и использовать на сайте.

Представьте короткую выдержку камеры, которая чуть вращается вокруг центра кадра. Точка вдали от центра оставляет дугообразный след; близкая к центру меняется меньше. Это лишь модель намеренного эффекта: PHP не снимает фотографию и не двигает камеру, а усредняет значения соседних выборок по дугам в готовом растре. Размер изображения не увеличивается. Объект хранит изображение, файл нужен для загрузки и сохранения результата.
$image->rotationalBlurImage(8.0);$image — переменная с объектом изображения; -> обращается к его методу; rotationalBlurImage — имя операции; в скобках 8.0 задаёт угол в градусах; ; завершает инструкцию. По окончании сам $image содержит изменённые пиксели. Если сохранить $status=$image->rotationalBlurImage(8.0), переменная $status получит true, а не картинку. Чтобы сохранить исходник, сначала делают clone. В полных программах явно выбираются RGB-каналы; одноаргументная запись выше показывает базовую форму.
Два похожих имени относятся к разным поколениям API. radialBlurImage — исторический метод, deprecated с Imagick 3.4.4. В точной сборке Imagick 3.8.1 его код включается только с ImageMagick 6 и разрешёнными deprecated-функциями; на проверенной ImageMagick 7 его нет. Современный rotationalBlurImage доступен с Imagick 3.3.0 и требует ImageMagick 6.8.9 или новее. Это направление миграции старого кода, а не PHP-псевдоним, который гарантированно существует под обоими именами. Все запускаемые программы ниже вызывают современное имя.
Сравнить исходник и два угла кругового размытия
Три панели показывают исходник и две независимые копии после 8° и 20°. Контуры растягиваются по дугам вокруг центра; весь прямоугольник остаётся 400 × 320. Это настоящие PNG современного rotationalBlurImage, а не жёсткий поворот картинки.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
$base = rotationParts();
rotationView($base, 'source-preview8.png');
$views = [$base]; $observed = [];
$rgb = Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE;
foreach ([8.0, 20.0] as $angle) {
$image = clone $base;
$before = rotationHash($image);
$ok = $image->rotationalBlurImage($angle, $rgb);
$name = 'angle'.(int)$angle.'.png';
rotationView($image, $name);
$views[] = new Imagick(__DIR__.'/'.$name);
$observed[] = ['angle'=>$angle, 'channel'=>$rgb, 'return_value'=>$ok,
'pixels_changed'=>$before !== rotationHash($image),
'virtual_pixel_method'=>$image->getImageVirtualPixelMethod(),
'pixels'=>rotationPixels($image)];
}
$rects = rotationCompare($views, 'rotational-first.png');
rotationDiagnostic('rotational-blur-first', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'cases'=>$observed, 'panel_geometry'=>$rects,
'checks'=>['modern_api_available'=>$modernAvailable,
'both_calls_true'=>array_column($observed,'return_value')===[true,true],
'both_outputs_changed'=>array_column($observed,'pixels_changed')===[true,true],
'three_distinct_panels'=>count(array_unique(array_map('rotationHash',$views)))===3]]);
echo "rotational-first.png\nsource-preview8.png\nangle8.png\nangle20.png\nmetrics.json\napi=rotationalBlurImage angles=8,20 channel=RGB\n";
Три панели показывают исходник и две независимые копии после 8° и 20°. Контуры растягиваются по дугам вокруг центра; весь прямоугольник остаётся 400 × 320. Это настоящие PNG современного rotationalBlurImage, а не жёсткий поворот картинки. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
rotational-first.png
source-preview8.png
angle8.png
angle20.png
metrics.json
api=rotationalBlurImage angles=8,20 channel=RGB
Понять дуги, градусы, центр и края кадра

У 400 × 320 входа Core использует центр ((400−1)/2, (320−1)/2) = (199.5, 159.5). Растр имеет целочисленные позиции пикселей, поэтому центр может находиться между ними. Для 20° образец строится по дуге примерно −10°..+10° относительно исходного направления. На схеме показан настоящий угол 20°, но три отмеченные точки выборки условны: это объяснение геометрии, а не точная трасса всех внутренних выборок и не движение реальных пикселей. Сохраняется расстояние до центра; соседние направления дают размытие вокруг, а не лучи приближения zoom.
| Что хотите сделать | Нужная операция |
|---|---|
| Добавить круговой смаз вокруг центра | rotationalBlurImage; параметр angle — угловой охват |
| Повернуть предмет на 8° | rotateImage; поворачивает растр, возможны интерполяция и изменение рамки |
| Равномерно смягчить фон без кругового следа | blurImage/gaussianBlurImage с radius/sigma |
| Получить направленный линейный след | motionBlurImage; иная модель с radius, sigma, angle |
| Размыть по лучам с эффектом приближения | Нужен отдельный zoom-алгоритм или иная обработка; историческое слово radial здесь не обещает zoom |
| Найти и исправить смаз камеры | Задача детекции/восстановления; этот фильтр её не решает |
У метода нет аргументов centerX/centerY. Чтобы сместить центр, придётся осознанно изменить холст и положение исходника, а затем вырезать результат. В этих программах виртуальная страница сброшена, холст 400 × 320, настройка virtual pixel не меняется. При выборке за рамкой библиотека использует своё правило виртуальных пикселей. Добавление полей заранее меняет и эту границу, и центр — это часть оформления, а не автоматическое поведение фильтра.
Запустить минимальный вызов и понять возвращаемое значение

Теперь достаточно одного вызова, чтения и сохранения. Архив уже содержит собственный рисунок; служебный helper подготавливает непрозрачный белый вход, чтобы изучение альфа-канала не скрывало сам эффект. Основная операция стоит отдельной строкой. Возвращённый bool выводим как true, а картинку сохраняем через writeImage в helper. Параметры не являются радиусом или числом повторов.
Создать один PNG с вращательным смазом 8°
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
$image = rotationParts();
$before = rotationHash($image);
$ok = $image->rotationalBlurImage(8.0,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
rotationView($image, 'rotational-minimal.png');
$changed = $before !== rotationHash($image);
rotationDiagnostic('rotational-blur-minimal', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>8.0, 'channel'=>7, 'return_value'=>$ok,
'pixels_changed'=>$changed, 'pixels'=>rotationPixels($image),
'checks'=>['modern_api_available'=>$modernAvailable,'success'=>$ok===true,
'pixels_changed'=>$changed,'same_geometry'=>$image->getImageWidth()===400&&$image->getImageHeight()===320]]);
printf("legacy=%d modern=%d set=%s changed=%d\n", (int)$legacyAvailable,
(int)$modernAvailable, $ok?'true':'false', (int)$changed);
echo "rotational-minimal.png\nmetrics.json\n";
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
legacy=0 modern=1 set=true changed=1
rotational-minimal.png
metrics.json
RED|GREEN|BLUE — побитовое объединение флагов трёх цветовых каналов. В точной IM7-обёртке эта явная маска действует во время вызова, затем прежняя настройка возвращается. Если второй аргумент пропущен, используется уже установленная на объекте маска. Поэтому для предсказуемого эффекта в этом RGB-шаблоне каналы названы явно. Вход заранее непрозрачен; пример не доказывает, что та же маска правильно размягчит прозрачный контур логотипа. Цветовая модель и типы изображения помогают продолжить эту тему.
Собрать фон с чётким окном и обработать ошибки

Практическое требование выросло: оформление должно привлекать внимание фоном, но центральная область должна оставаться читаемой. Функция rotatingBackground получает исходный объект и угол, проверяет настройку, создаёт clone и возвращает новый объект. Затем из исходника вырезается строго заданное окно 240 × 192 с координатами 80,64 и кладётся поверх фона в то же место. Это фиксированный учебный шаблон 400 × 320; он не обещает автоматически распознать и защитить весь товар на произвольной фотографии.
Оставить чёткое центральное окно на вращательно размытом фоне
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
function rotatingBackground(Imagick $input, float $angle): Imagick {
// This is the application's policy, not the library's documented range.
if (!is_finite($angle) || $angle < 0.0 || $angle > 30.0) {
throw new InvalidArgumentException('Angle must be finite and in 0..30');
}
$result = clone $input;
$result->rotationalBlurImage($angle,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
return $result;
}
$base = rotationParts(); $sourceBefore = rotationHash($base);
$background = rotatingBackground($base, 20.0);
rotationView($background, 'background20.png');
// Keep a sharp central window. This is a fixed-size teaching template.
$foreground = clone $base;
$foreground->cropImage(240, 192, 80, 64);
$foreground->setImagePage(0, 0, 0, 0);
$hero = clone $background;
$hero->compositeImage($foreground, Imagick::COMPOSITE_OVER, 80, 64);
rotationView($hero, 'sharp-center.png');
$center = clone $hero;
$center->cropImage(240, 192, 80, 64); $center->setImagePage(0, 0, 0, 0);
$sharp = rotationHash($center) === rotationHash($foreground);
$rejected = [];
foreach ([-8.0, 31.0, NAN] as $badAngle) {
try { rotatingBackground($base, $badAngle); $rejected[]='not caught'; }
catch (InvalidArgumentException $error) { $rejected[]=get_class($error); }
}
$emptyError = 'not caught';
try { (new Imagick())->rotationalBlurImage(8.0); }
catch (ImagickException $error) { $emptyError=get_class($error); }
$unchanged = $sourceBefore === rotationHash($base);
rotationView($base, 'rejected-input.png');
$rects = rotationCompare([$background, $hero, $base], 'rotational-workflow.png');
rotationDiagnostic('rotational-blur-workflow', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>20.0, 'channel'=>7, 'sharp_window'=>['x'=>80,'y'=>64,'width'=>240,'height'=>192],
'sharp_center_preserved'=>$sharp, 'rejected_policy'=>$rejected,
'empty_error'=>$emptyError, 'source_unchanged'=>$unchanged,
'panel_geometry'=>$rects, 'checks'=>['modern_api_available'=>$modernAvailable,
'sharp_center_preserved'=>$sharp,'source_unchanged'=>$unchanged,
'invalid_angles_rejected'=>$rejected===array_fill(0,3,'InvalidArgumentException'),
'empty_image_error_caught'=>$emptyError==='ImagickException',
'background_changed'=>$sourceBefore!==rotationHash($background)]]);
echo "rotational-workflow.png\nbackground20.png\nsharp-center.png\nrejected-input.png\nmetrics.json\nsharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1\n";
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
rotational-workflow.png
background20.png
sharp-center.png
rejected-input.png
metrics.json
sharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1
После cropImage сбрасываем виртуальную страницу, чтобы вырезанный фрагмент не нёс старое смещение. compositeImage(…,OVER,80,64) покрывает фон чётким непрозрачным окном. Внутри этого прямоугольника пиксели совпадают с оригиналом; вне него остаётся размытие. Если нужен весь товар без обрезки, подайте отдельно подготовленный передний слой/маску, а не этот прямоугольный crop. Операторы композиции объясняют объединение слоёв.
Диапазон 0..30 и условие is_finite — наша политика интерфейса, а не документированный предел библиотеки. NAN означает специальное значение «не число»; мы передаём его только для проверки отказа. Отрицательный угол библиотека может принять, но нельзя обещать, что он просто изменит направление при той же силе: точная формула числа выборок отличается. Поэтому пользовательская настройка ограничена. Некорректный угол отклонён до обработки; исходник сохранён. Отдельный пустой Imagick вызывает настоящую ImagickException, которую ловим и показываем как отказ, а не успешный PNG.
Сохранить оба официальных контракта и выбрать следующий шаг
rotationalBlurImage намеренно размывает текущее изображение вокруг его центра. Метод нужен для художественного кругового движения и оформления фона; он не выявляет уже смазанные фотографии и не восстанавливает потерянную резкость.
Imagick::rotationalBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): bool| Часть записи | Что передать и что произойдёт |
|---|---|
| $angle:float, обязательный | Угловой охват размытия в градусах. Это не радиус в пикселях, не процент и не угол поворота всей картинки. Для 8° выборки охватывают примерно −4°..+4° вокруг исходного направления. |
| $channel:int, необязательный | В официальной записи CHANNEL_DEFAULT. В явном RGB-вызове RED|GREEN|BLUE объединяет три канала. Для нынешней IM7-обёртки явно переданная маска временно назначается и восстанавливается; пропущенный аргумент сохраняет уже выбранную текущую маску. |
| bool true | Статус успешной обработки; изображение изменяется внутри объекта. Возвращаемое значение не является новым объектом или байтами PNG. |
| Ошибка | Пустое изображение и ошибка библиотеки превращаются в ImagickException. Ошибка чтения файла возможна до фильтра; отсутствие самого метода требует проверки method_exists. |
Официальная доступность: PECL imagick 3 >= 3.3.0. В точных исходниках Imagick 3.8.1 метод включается при MagickLibVersion≥0x689. Параметр channel зависит от цветовой модели; RGB-маска этой главы применяется к непрозрачному RGB-входу и не является универсальным выбором для CMYK или прозрачного PNG.
Что делает официальный пример
В нём функция получает путь, читает realpath и трижды обрабатывает один объект: сначала 3, затем 5, затем 7. Это последовательное накопление обработки, а не сравнение трёх исходных копий; результат не следует автоматически считать равным одному вызову 15. В старом radial-примере комментарий говорит radii, но передаётся именно angle. Функция только объявлена: для запуска нужен существующий путь и её вызов. HTTP-ответ отправляет Content-Type: image/jpg и getImageBlob, однако конкретный формат надо согласовать с байтами, например явно setImageFormat("jpeg"). Текстовая диагностика не должна попадать перед изображением. Ниже доступны самостоятельные CLI-программы с фиксированным собственным PNG, явным форматом и видимыми результатами.
Полный официальный XML и оригинальный пример без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xml:id="imagick.rotationalblurimage" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Imagick::rotationalBlurImage</refname>
<refpurpose>Rotational blurs an image</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::rotationalBlurImage</methodname>
<methodparam><type>float</type><parameter>angle</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
</methodsynopsis>
<para>
Rotational blurs an image.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<variablelist>
<varlistentry>
<term><parameter>angle</parameter></term>
<listitem>
<para>
The angle to apply the blur over.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>channel</parameter></term>
<listitem>
<para>
&imagick.parameter.channel;
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::rotationalBlurImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function rotationalBlurImage($imagePath) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->rotationalBlurImage(3);
$imagick->rotationalBlurImage(5);
$imagick->rotationalBlurImage(7);
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
-->
Два похожих имени относятся к разным поколениям API. radialBlurImage — исторический метод, deprecated с Imagick 3.4.4. В точной сборке Imagick 3.8.1 его код включается только с ImageMagick 6 и разрешёнными deprecated-функциями; на проверенной ImageMagick 7 его нет. Современный rotationalBlurImage доступен с Imagick 3.3.0 и требует ImageMagick 6.8.9 или новее. Это направление миграции старого кода, а не PHP-псевдоним, который гарантированно существует под обоими именами. Все запускаемые программы ниже вызывают современное имя.
Imagick::radialBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): bool| Часть записи | Что передать и что произойдёт |
|---|---|
| $angle:float, обязательный | Угловой охват размытия в градусах. Это не радиус в пикселях, не процент и не угол поворота всей картинки. Для 8° выборки охватывают примерно −4°..+4° вокруг исходного направления. |
| $channel:int, необязательный | В официальной записи CHANNEL_DEFAULT. В явном RGB-вызове RED|GREEN|BLUE объединяет три канала. Для нынешней IM7-обёртки явно переданная маска временно назначается и восстанавливается; пропущенный аргумент сохраняет уже выбранную текущую маску. |
| bool true | Статус успешной обработки; изображение изменяется внутри объекта. Возвращаемое значение не является новым объектом или байтами PNG. |
| Ошибка | Пустое изображение и ошибка библиотеки превращаются в ImagickException. Ошибка чтения файла возможна до фильтра; отсутствие самого метода требует проверки method_exists. |
Официальная доступность: PECL imagick 2, PECL imagick 3. У старой страницы пояснения обоих параметров пусты. Сигнатуру, описание, статус успеха и полный оригинальный пример сохраняем; градусы, каналы и миграцию объясняем отдельно по точным исходникам, не выдавая дополнение за текст оригинала.
Что делает официальный пример
В нём функция получает путь, читает realpath и трижды обрабатывает один объект: сначала 3, затем 5, затем 7. Это последовательное накопление обработки, а не сравнение трёх исходных копий; результат не следует автоматически считать равным одному вызову 15. В старом radial-примере комментарий говорит radii, но передаётся именно angle. Функция только объявлена: для запуска нужен существующий путь и её вызов. HTTP-ответ отправляет Content-Type: image/jpg и getImageBlob, однако конкретный формат надо согласовать с байтами, например явно setImageFormat("jpeg"). Текстовая диагностика не должна попадать перед изображением. Исторический пример требует старой совместимой сборки и на проверенной IM7 не выполнялся.
Полный официальный XML и оригинальный пример без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.radialblurimage">
<refnamediv>
<refname>Imagick::radialBlurImage</refname>
<refpurpose>Radial blurs an image</refpurpose>
</refnamediv>
<refsynopsisdiv>
&imagick.deprecated.function-3-4-4;
</refsynopsisdiv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::radialBlurImage</methodname>
<methodparam><type>float</type><parameter>angle</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
</methodsynopsis>
<para>
Radial blurs an image.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>angle</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>channel</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::radialBlurImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function radialBlurImage($imagePath) {
$imagick = new \Imagick(realpath($imagePath));
//Blur 3 times with different radii
$imagick->radialBlurImage(3);
$imagick->radialBlurImage(5);
$imagick->radialBlurImage(7);
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
-->
Замена в текущем коде
// Historical, unavailable on the tested IM7 build:
// $image->radialBlurImage(8.0, Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
$image->rotationalBlurImage(8.0, Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);Это фрагмент миграции. Проверка доступности, чтение, запись и реальные результаты современного вызова находятся в двух самостоятельных примерах ниже. Мы подтверждаем запуск альтернативы, а не отсутствующего исторического метода.
Каждый вызов работает с текущим кадром объекта. Для анимации недостаточно обработать только один выбранный кадр: нужна отдельная подготовка последовательности и обдуманное применение к кадрам. Эти примеры сознательно используют один PNG. Результаты записаны в RGB8 PNG: это не измерение размера JPEG и не рекомендация повторно фильтровать уже пережатый оригинал.
Чем больше изображение и угловой охват, тем больше работы с выборками; время зависит также от версии, сборки, каналов и аппаратного ускорения. Нет универсального соответствия «20° = 20 процентов» и универсальной цены в миллисекундах. Храните исходник, готовьте отдельные производные и измеряйте собственные размеры. Жёсткий поворот и многократное размытие не заменяют друг друга; увеличение JPEG quality не возвращает детали, усреднённые фильтром.
Упражнение и решение
Сделайте два оформления с одним чётким окном: угол 8° и 20°. Решение: дважды вызвать rotatingBackground на одном неизменённом $base, для каждого результата накладывать clone того же центрального фрагмента. Не вызывайте 8 затем 20 на одной фоновой копии, иначе сравните накопленную обработку. Проверяйте геометрию окна и сохраняйте исходник отдельно.
Полный helper подготовки собственного входа
<?php
declare(strict_types=1);
function rotationRestore():void {$raw=base64_decode((string)file_get_contents(__DIR__.'/source.png.b64'),true);if($raw===false||hash('sha256',$raw)!=='f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c'||file_put_contents(__DIR__.'/source.png',$raw)===false){throw new RuntimeException('Own source missing or changed');}}
function rotationHash(Imagick $image):string {return hash('sha256',json_encode($image->exportImagePixels(0,0,$image->getImageWidth(),$image->getImageHeight(),'RGBA',Imagick::PIXEL_CHAR),JSON_THROW_ON_ERROR));}
function rotationPixels(Imagick $image):array {return ['width'=>$image->getImageWidth(),'height'=>$image->getImageHeight(),'RGBA8_hash'=>rotationHash($image)];}
function rotationOpaque(Imagick $image):Imagick {$view=new Imagick();$view->newImage($image->getImageWidth(),$image->getImageHeight(),'white');$view->compositeImage($image,Imagick::COMPOSITE_OVER,0,0);$view->setImageType(Imagick::IMGTYPE_TRUECOLOR);return $view;}
function rotationView(Imagick $image,string $filename):void {$view=rotationOpaque($image);$view->setImageFormat('png');$view->setImageDepth(8);$view->setOption('png:bit-depth','8');$view->setOption('png:color-type','2');$view->setOption('png:exclude-chunk','all');if(!$view->writeImage(__DIR__.'/'.$filename)){throw new RuntimeException('PNG preview write failed');}}
function rotationParts():Imagick {
$source=new Imagick(__DIR__.'/source.png');$base=new Imagick();$base->newImage(400,320,'white');$base->compositeImage($source,Imagick::COMPOSITE_OVER,0,0);$base->setImagePage(0,0,0,0);return $base;
}
function rotationCompare(array $images,string $filename):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 a complete 400x320 panel');}$board->compositeImage($image,Imagick::COMPOSITE_OVER,400*$i,0);$rects[]=['x'=>400*$i,'y'=>0,'width'=>400,'height'=>320];}rotationView($board,$filename);return $rects;}
function rotationDiagnostic(string $id,array $data):void {$doc=['schema'=>'aen-rotational-blur-program-diagnostics-v1','example_id'=>$id]+$data;if(file_put_contents(__DIR__.'/metrics.json',json_encode($doc,JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION|JSON_THROW_ON_ERROR)."\n")===false){throw new RuntimeException('Diagnostic write failed');}}
Helper занимается восстановлением файла, белой основой, RGB8-просмотром, сборкой сравнительных панелей и диагностикой. Он не скрывает вызов изучаемого метода. Для веб-ответа отдавайте PNG отдельным обработчиком с Content-Type: image/png; CLI-диагностику нельзя выводить вперемешку с бинарными байтами. Далее: слои, холст и вырезание, клонирование и обработка исключений.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::rotationalBlurImageКруговой смаз в градусах с сохранением исходника
PECL imagick 3 >= 3.3.0 · imagick
Imagick::rotationalBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): boolrotationalBlurImage намеренно размывает текущее изображение вокруг его центра. Метод нужен для художественного кругового движения и оформления фона; он не выявляет уже смазанные фотографии и не восстанавливает потерянную резкость.
Imagick::rotationalBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): bool| Часть записи | Что передать и что произойдёт |
|---|---|
| $angle:float, обязательный | Угловой охват размытия в градусах. Это не радиус в пикселях, не процент и не угол поворота всей картинки. Для 8° выборки охватывают примерно −4°..+4° вокруг исходного направления. |
| $channel:int, необязательный | В официальной записи CHANNEL_DEFAULT. В явном RGB-вызове RED|GREEN|BLUE объединяет три канала. Для нынешней IM7-обёртки явно переданная маска временно назначается и восстанавливается; пропущенный аргумент сохраняет уже выбранную текущую маску. |
| bool true | Статус успешной обработки; изображение изменяется внутри объекта. Возвращаемое значение не является новым объектом или байтами PNG. |
| Ошибка | Пустое изображение и ошибка библиотеки превращаются в ImagickException. Ошибка чтения файла возможна до фильтра; отсутствие самого метода требует проверки method_exists. |
Официальная доступность: PECL imagick 3 >= 3.3.0. В точных исходниках Imagick 3.8.1 метод включается при MagickLibVersion≥0x689. Параметр channel зависит от цветовой модели; RGB-маска этой главы применяется к непрозрачному RGB-входу и не является универсальным выбором для CMYK или прозрачного PNG.
Что делает официальный пример
В нём функция получает путь, читает realpath и трижды обрабатывает один объект: сначала 3, затем 5, затем 7. Это последовательное накопление обработки, а не сравнение трёх исходных копий; результат не следует автоматически считать равным одному вызову 15. В старом radial-примере комментарий говорит radii, но передаётся именно angle. Функция только объявлена: для запуска нужен существующий путь и её вызов. HTTP-ответ отправляет Content-Type: image/jpg и getImageBlob, однако конкретный формат надо согласовать с байтами, например явно setImageFormat("jpeg"). Текстовая диагностика не должна попадать перед изображением. Ниже доступны самостоятельные CLI-программы с фиксированным собственным PNG, явным форматом и видимыми результатами.
Полный официальный XML и оригинальный пример без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xml:id="imagick.rotationalblurimage" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Imagick::rotationalBlurImage</refname>
<refpurpose>Rotational blurs an image</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::rotationalBlurImage</methodname>
<methodparam><type>float</type><parameter>angle</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
</methodsynopsis>
<para>
Rotational blurs an image.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<variablelist>
<varlistentry>
<term><parameter>angle</parameter></term>
<listitem>
<para>
The angle to apply the blur over.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>channel</parameter></term>
<listitem>
<para>
&imagick.parameter.channel;
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::rotationalBlurImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function rotationalBlurImage($imagePath) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->rotationalBlurImage(3);
$imagick->rotationalBlurImage(5);
$imagick->rotationalBlurImage(7);
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
-->
Создать один PNG с вращательным смазом 8°
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
$image = rotationParts();
$before = rotationHash($image);
$ok = $image->rotationalBlurImage(8.0,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
rotationView($image, 'rotational-minimal.png');
$changed = $before !== rotationHash($image);
rotationDiagnostic('rotational-blur-minimal', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>8.0, 'channel'=>7, 'return_value'=>$ok,
'pixels_changed'=>$changed, 'pixels'=>rotationPixels($image),
'checks'=>['modern_api_available'=>$modernAvailable,'success'=>$ok===true,
'pixels_changed'=>$changed,'same_geometry'=>$image->getImageWidth()===400&&$image->getImageHeight()===320]]);
printf("legacy=%d modern=%d set=%s changed=%d\n", (int)$legacyAvailable,
(int)$modernAvailable, $ok?'true':'false', (int)$changed);
echo "rotational-minimal.png\nmetrics.json\n";
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
legacy=0 modern=1 set=true changed=1
rotational-minimal.png
metrics.json
Оставить чёткое центральное окно на вращательно размытом фоне
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
function rotatingBackground(Imagick $input, float $angle): Imagick {
// This is the application's policy, not the library's documented range.
if (!is_finite($angle) || $angle < 0.0 || $angle > 30.0) {
throw new InvalidArgumentException('Angle must be finite and in 0..30');
}
$result = clone $input;
$result->rotationalBlurImage($angle,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
return $result;
}
$base = rotationParts(); $sourceBefore = rotationHash($base);
$background = rotatingBackground($base, 20.0);
rotationView($background, 'background20.png');
// Keep a sharp central window. This is a fixed-size teaching template.
$foreground = clone $base;
$foreground->cropImage(240, 192, 80, 64);
$foreground->setImagePage(0, 0, 0, 0);
$hero = clone $background;
$hero->compositeImage($foreground, Imagick::COMPOSITE_OVER, 80, 64);
rotationView($hero, 'sharp-center.png');
$center = clone $hero;
$center->cropImage(240, 192, 80, 64); $center->setImagePage(0, 0, 0, 0);
$sharp = rotationHash($center) === rotationHash($foreground);
$rejected = [];
foreach ([-8.0, 31.0, NAN] as $badAngle) {
try { rotatingBackground($base, $badAngle); $rejected[]='not caught'; }
catch (InvalidArgumentException $error) { $rejected[]=get_class($error); }
}
$emptyError = 'not caught';
try { (new Imagick())->rotationalBlurImage(8.0); }
catch (ImagickException $error) { $emptyError=get_class($error); }
$unchanged = $sourceBefore === rotationHash($base);
rotationView($base, 'rejected-input.png');
$rects = rotationCompare([$background, $hero, $base], 'rotational-workflow.png');
rotationDiagnostic('rotational-blur-workflow', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>20.0, 'channel'=>7, 'sharp_window'=>['x'=>80,'y'=>64,'width'=>240,'height'=>192],
'sharp_center_preserved'=>$sharp, 'rejected_policy'=>$rejected,
'empty_error'=>$emptyError, 'source_unchanged'=>$unchanged,
'panel_geometry'=>$rects, 'checks'=>['modern_api_available'=>$modernAvailable,
'sharp_center_preserved'=>$sharp,'source_unchanged'=>$unchanged,
'invalid_angles_rejected'=>$rejected===array_fill(0,3,'InvalidArgumentException'),
'empty_image_error_caught'=>$emptyError==='ImagickException',
'background_changed'=>$sourceBefore!==rotationHash($background)]]);
echo "rotational-workflow.png\nbackground20.png\nsharp-center.png\nrejected-input.png\nmetrics.json\nsharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1\n";
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
rotational-workflow.png
background20.png
sharp-center.png
rejected-input.png
metrics.json
sharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1
Imagick::radialBlurImageИсторическое круговое размытие и актуальная замена
PECL imagick 2, PECL imagick 3 · imagick
Imagick::radialBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): boolДва похожих имени относятся к разным поколениям API. radialBlurImage — исторический метод, deprecated с Imagick 3.4.4. В точной сборке Imagick 3.8.1 его код включается только с ImageMagick 6 и разрешёнными deprecated-функциями; на проверенной ImageMagick 7 его нет. Современный rotationalBlurImage доступен с Imagick 3.3.0 и требует ImageMagick 6.8.9 или новее. Это направление миграции старого кода, а не PHP-псевдоним, который гарантированно существует под обоими именами. Все запускаемые программы ниже вызывают современное имя.
Imagick::radialBlurImage(float $angle, int $channel = Imagick::CHANNEL_DEFAULT): bool| Часть записи | Что передать и что произойдёт |
|---|---|
| $angle:float, обязательный | Угловой охват размытия в градусах. Это не радиус в пикселях, не процент и не угол поворота всей картинки. Для 8° выборки охватывают примерно −4°..+4° вокруг исходного направления. |
| $channel:int, необязательный | В официальной записи CHANNEL_DEFAULT. В явном RGB-вызове RED|GREEN|BLUE объединяет три канала. Для нынешней IM7-обёртки явно переданная маска временно назначается и восстанавливается; пропущенный аргумент сохраняет уже выбранную текущую маску. |
| bool true | Статус успешной обработки; изображение изменяется внутри объекта. Возвращаемое значение не является новым объектом или байтами PNG. |
| Ошибка | Пустое изображение и ошибка библиотеки превращаются в ImagickException. Ошибка чтения файла возможна до фильтра; отсутствие самого метода требует проверки method_exists. |
Официальная доступность: PECL imagick 2, PECL imagick 3. У старой страницы пояснения обоих параметров пусты. Сигнатуру, описание, статус успеха и полный оригинальный пример сохраняем; градусы, каналы и миграцию объясняем отдельно по точным исходникам, не выдавая дополнение за текст оригинала.
Что делает официальный пример
В нём функция получает путь, читает realpath и трижды обрабатывает один объект: сначала 3, затем 5, затем 7. Это последовательное накопление обработки, а не сравнение трёх исходных копий; результат не следует автоматически считать равным одному вызову 15. В старом radial-примере комментарий говорит radii, но передаётся именно angle. Функция только объявлена: для запуска нужен существующий путь и её вызов. HTTP-ответ отправляет Content-Type: image/jpg и getImageBlob, однако конкретный формат надо согласовать с байтами, например явно setImageFormat("jpeg"). Текстовая диагностика не должна попадать перед изображением. Исторический пример требует старой совместимой сборки и на проверенной IM7 не выполнялся.
Полный официальный XML и оригинальный пример без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.radialblurimage">
<refnamediv>
<refname>Imagick::radialBlurImage</refname>
<refpurpose>Radial blurs an image</refpurpose>
</refnamediv>
<refsynopsisdiv>
&imagick.deprecated.function-3-4-4;
</refsynopsisdiv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::radialBlurImage</methodname>
<methodparam><type>float</type><parameter>angle</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>channel</parameter><initializer>Imagick::CHANNEL_DEFAULT</initializer></methodparam>
</methodsynopsis>
<para>
Radial blurs an image.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>angle</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>channel</parameter></term>
<listitem>
<para>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&imagick.return.success;
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title> <function>Imagick::radialBlurImage</function></title>
<programlisting role="php">
<![CDATA[
<?php
function radialBlurImage($imagePath) {
$imagick = new \Imagick(realpath($imagePath));
//Blur 3 times with different radii
$imagick->radialBlurImage(3);
$imagick->radialBlurImage(5);
$imagick->radialBlurImage(7);
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
-->
Замена в текущем коде
// Historical, unavailable on the tested IM7 build:
// $image->radialBlurImage(8.0, Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
$image->rotationalBlurImage(8.0, Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);Это фрагмент миграции. Проверка доступности, чтение, запись и реальные результаты современного вызова находятся в двух самостоятельных примерах ниже. Мы подтверждаем запуск альтернативы, а не отсутствующего исторического метода.
Создать один PNG с вращательным смазом 8°
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
$image = rotationParts();
$before = rotationHash($image);
$ok = $image->rotationalBlurImage(8.0,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
rotationView($image, 'rotational-minimal.png');
$changed = $before !== rotationHash($image);
rotationDiagnostic('rotational-blur-minimal', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>8.0, 'channel'=>7, 'return_value'=>$ok,
'pixels_changed'=>$changed, 'pixels'=>rotationPixels($image),
'checks'=>['modern_api_available'=>$modernAvailable,'success'=>$ok===true,
'pixels_changed'=>$changed,'same_geometry'=>$image->getImageWidth()===400&&$image->getImageHeight()===320]]);
printf("legacy=%d modern=%d set=%s changed=%d\n", (int)$legacyAvailable,
(int)$modernAvailable, $ok?'true':'false', (int)$changed);
echo "rotational-minimal.png\nmetrics.json\n";
Один вызов изменил цветовые каналы текущего изображения, вернул true и сохранил размер 400 × 320. В проверенной IM7-сборке историческое radialBlurImage отсутствует, современное имя доступно. Результат записан в отдельный PNG. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
legacy=0 modern=1 set=true changed=1
rotational-minimal.png
metrics.json
Оставить чёткое центральное окно на вращательно размытом фоне
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки.
<?php
declare(strict_types=1);
require __DIR__.'/rotation-fixture.php';
rotationRestore();
$legacyAvailable = method_exists(Imagick::class, 'radialBlurImage');
$modernAvailable = method_exists(Imagick::class, 'rotationalBlurImage');
if (!$modernAvailable) { throw new RuntimeException('This example needs rotationalBlurImage'); }
function rotatingBackground(Imagick $input, float $angle): Imagick {
// This is the application's policy, not the library's documented range.
if (!is_finite($angle) || $angle < 0.0 || $angle > 30.0) {
throw new InvalidArgumentException('Angle must be finite and in 0..30');
}
$result = clone $input;
$result->rotationalBlurImage($angle,
Imagick::CHANNEL_RED | Imagick::CHANNEL_GREEN | Imagick::CHANNEL_BLUE);
return $result;
}
$base = rotationParts(); $sourceBefore = rotationHash($base);
$background = rotatingBackground($base, 20.0);
rotationView($background, 'background20.png');
// Keep a sharp central window. This is a fixed-size teaching template.
$foreground = clone $base;
$foreground->cropImage(240, 192, 80, 64);
$foreground->setImagePage(0, 0, 0, 0);
$hero = clone $background;
$hero->compositeImage($foreground, Imagick::COMPOSITE_OVER, 80, 64);
rotationView($hero, 'sharp-center.png');
$center = clone $hero;
$center->cropImage(240, 192, 80, 64); $center->setImagePage(0, 0, 0, 0);
$sharp = rotationHash($center) === rotationHash($foreground);
$rejected = [];
foreach ([-8.0, 31.0, NAN] as $badAngle) {
try { rotatingBackground($base, $badAngle); $rejected[]='not caught'; }
catch (InvalidArgumentException $error) { $rejected[]=get_class($error); }
}
$emptyError = 'not caught';
try { (new Imagick())->rotationalBlurImage(8.0); }
catch (ImagickException $error) { $emptyError=get_class($error); }
$unchanged = $sourceBefore === rotationHash($base);
rotationView($base, 'rejected-input.png');
$rects = rotationCompare([$background, $hero, $base], 'rotational-workflow.png');
rotationDiagnostic('rotational-blur-workflow', ['legacy_available'=>$legacyAvailable,
'modern_available'=>$modernAvailable, 'executed_api'=>'rotationalBlurImage',
'angle'=>20.0, 'channel'=>7, 'sharp_window'=>['x'=>80,'y'=>64,'width'=>240,'height'=>192],
'sharp_center_preserved'=>$sharp, 'rejected_policy'=>$rejected,
'empty_error'=>$emptyError, 'source_unchanged'=>$unchanged,
'panel_geometry'=>$rects, 'checks'=>['modern_api_available'=>$modernAvailable,
'sharp_center_preserved'=>$sharp,'source_unchanged'=>$unchanged,
'invalid_angles_rejected'=>$rejected===array_fill(0,3,'InvalidArgumentException'),
'empty_image_error_caught'=>$emptyError==='ImagickException',
'background_changed'=>$sourceBefore!==rotationHash($background)]]);
echo "rotational-workflow.png\nbackground20.png\nsharp-center.png\nrejected-input.png\nmetrics.json\nsharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1\n";
Фон обработан на 20°, поверх положен чёткий центральный фрагмент 240 × 192. Оригинал сохранён отдельно. Отрицательное, слишком большое и нечисловое NAN-значение отклоняет политика приложения; отдельно перехвачена настоящая ImagickException от пустого объекта. Последняя панель — исходник после отказа, а не результат успешной обработки. Архив содержит example.php и два текстовых файла: source.png.b64 и rotation-fixture.php. Сохраните рядом, выполните php example.php с Imagick, поддержкой PNG и правом записи. Helper восстанавливает собственную иллюстрацию по SHA, накладывает её на белую основу 400 × 320 и сбрасывает виртуальную страницу; вызываемый rotationalBlurImage виден в программе. Все три программы проверены в текущей сборке, историческое имя не выполнялось.
Ожидаемый вывод
rotational-workflow.png
background20.png
sharp-center.png
rejected-input.png
metrics.json
sharp-window=240x192 invalid-angles=3 empty=ImagickException source-unchanged=1
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


