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

Дерево руководства
Глава 376 · После переменных, объектов, файлов и последовательностей Imagick
Imagick: gravity текущего изображения и настоящее выравнивание карточек
Увидеть реальный append, прочитать и изменить свойство нужного кадра, отличить Draw/Wand и абсолютные координаты.
Получить понятное выравнивание двух карточек
Нужно поставить рядом две карточки разной высоты: полную карточку товара и небольшое превью. По умолчанию короткая картинка оказывается сверху; в макете её хочется выровнять по центру или снизу. Сначала посмотрите три реально собранных PNG. Справа одна и та же картинка200×160 занимает y=0,80 или160 на холсте400×320. Слева карточка200×320 остаётся на месте.

Gravity здесь означает правило привязки: сверху, по центру или снизу; это не сила тяжести и не готовая пара x/y. У объекта есть текущее изображение, а в последовательности текущий кадр выбирает iterator. $image — переменная с объектом; -> вызывает метод, () содержит аргументы, ; завершает инструкцию. Imagick::GRAVITY_SOUTH — именованная целочисленная константа. Getter получает значение без аргументов; setter записывает одно значение. Переменные, объекты и последовательности Imagick — связанные объяснения.
Оригинальная собственная иллюстрация400×320 явно уменьшена PHP до200×160; рамка нарисована внутри, поэтому размеры не выросли. Высокая карточка содержит эту иллюстрацию и условные графические полосы описания — это учебный макет, а не текст товара. Helper не прячет изучаемые вызовы: программа выбирает кадр, задаёт gravity и вызывает appendImages(false). false означает слева направо; возвращается новый Imagick с результатом. Затем он записывается как отдельный PNG.
Собрать карточки разной высоты и увидеть выравнивание
Три настоящих PNG показывают короткую карточку справа сверху, по центру и снизу. Растр меняет appendImages, который читает gravity каждого кадра; один setter пиксели не передвигал.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
[$tall,$tile]=gravityParts();$views=[];$observed=[];
gravityView(new Imagick(__DIR__.'/source.png'),'source-preview8.png');
foreach(['north'=>Imagick::GRAVITY_NORTHWEST,'center'=>Imagick::GRAVITY_CENTER,'south'=>Imagick::GRAVITY_SOUTH] as $name=>$wanted){
$sequence=new Imagick();$sequence->addImage($tall);$sequence->addImage($tile);
$sequence->setFirstIterator();$sequence->setImageGravity(Imagick::GRAVITY_NORTHWEST);
$sequence->setIteratorIndex(1);$before=gravityHash($sequence);
$ok=$sequence->setImageGravity($wanted);$current=$sequence->getImageGravity();$same=$before===gravityHash($sequence);
$sequence->setFirstIterator();$sequence->setImageBackgroundColor('white');
$result=$sequence->appendImages(false); // false joins left-to-right; each frame supplies its own alignment.
gravityView($result,$name.'-append.png');$views[]=new Imagick(__DIR__.'/'.$name.'-append.png');
$observed[]=['name'=>$name,'requested'=>$wanted,'current'=>$current,'setter_return'=>$ok,'pixels_unchanged_by_setter'=>$same,'output'=>gravityPixels($result)];
}
$rects=gravityCompare($views,'gravity-first.png');
gravityDiagnostic('image-gravity-first',['cases'=>$observed,'panel_geometry'=>$rects,'checks'=>['three_real_alignments'=>count(array_unique(array_map('gravityHash',$views)))===3,'setter_only_keeps_pixels'=>!in_array(false,array_column($observed,'pixels_unchanged_by_setter'),true),'properties_match_request'=>array_column($observed,'current')===array_column($observed,'requested')]]);
echo "gravity-first.png\nsource-preview8.png\nnorth-append.png\ncenter-append.png\nsouth-append.png\nmetrics.json\nalignments=3 setter-keeps-pixels=1\n";
Три настоящих PNG показывают короткую карточку справа сверху, по центру и снизу. Растр меняет appendImages, который читает gravity каждого кадра; один setter пиксели не передвигал. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity-first.png
source-preview8.png
north-append.png
center-append.png
south-append.png
metrics.json
alignments=3 setter-keeps-pixels=1
Разделить свойство, контекст и фактическое размещение

Знакомая модель — выравнивание картинок в строке. У короткой картинки есть правило «по нижнему краю»; компоновщик использует высоту строки, чтобы найти место. Аналогия ограничена этой задачей: Imagick не является CSS-layout, не вычисляет автоматически интервалы/переносы и не заставляет все методы читать gravity. Setter записывает предпочтение в объект; растр создаёт последующий consumer.
| Где хранится правило | Как читаем/задаём | Кто использует |
|---|---|---|
| Текущее изображение/кадр | getImageGravity / setImageGravity | Например, appendImages читает gravity каждого участвующего кадра |
| Контекст Wand image_info | getGravity / setGravity | Отдельная настройка; не переписывает уже существующие кадры |
| Объект рисования ImagickDraw | getGravity / setGravity у Draw | Правила текста/рисования в DrawInfo, отдельные от image->gravity |
| Аргумент конкретного метода | compositeImageGravity(...,$gravity) | Явное значение передано в вызов; getter можно использовать как источник аргумента |
| Абсолютные координаты | compositeImage(...,$x,$y) | Положение определяется числами x/y; imagegravity не подменяет их |
В точном Core AppendImages цикл вызывает GravityAdjustGeometry с next->gravity каждого кадра. Первый кадр также задаёт фон результирующего холста. До append здесь вызывается setFirstIterator, потому что операция начинает с текущего изображения и идёт к концу. setImageGravity влияет только на выбранный кадр; один вызов не является рассылкой всем кадрам.
Прочитать именно выбранное изображение и применить значение

Gravity здесь означает правило привязки: сверху, по центру или снизу; это не сила тяжести и не готовая пара x/y. У объекта есть текущее изображение, а в последовательности текущий кадр выбирает iterator. $image — переменная с объектом; -> вызывает метод, () содержит аргументы, ; завершает инструкцию. Imagick::GRAVITY_SOUTH — именованная целочисленная константа. Getter получает значение без аргументов; setter записывает одно значение. Переменные, объекты и последовательности Imagick — связанные объяснения.
Минимальная запись и полный официальный контракт
Imagick::getImageGravity(): int$gravity = $image->getImageGravity();Параметров нет; возвращается int — gravity текущего изображения, одна из констант семейства GRAVITY_*. Официальная запись отличает метод от getGravity и говорит о текущей последовательности. Exact C уточняет: читается image->gravity именно текущего кадра, не общий результат всех кадров. Если выбрать другой кадр, число может измениться. У этого известного собственного исходника наблюдается незаданное Core-значение0; не трактуйте0 как координату или универсальный код ошибки.
Доступность: PECL imagick 2 >= 2.3.0, PECL imagick 3; оба метода требуют сборку с ImageMagick6.4.4 или новее. В исходных официальных записях нет примеров кода и отдельного раздела ошибок. Текущий PHP wrapper проверяет непустой Imagick: без изображения оба метода дают ImagickException; неверный путь может завершиться исключением ещё в new Imagick, до getter/setter. Неверный PHP-тип/число аргументов обрабатывает PHP binding. Это уточнение фактического поведения, а не выдуманный текст официальной страницы.
Именованные положения
| Слева | По центру | Справа |
|---|---|---|
| GRAVITY_NORTHWEST | GRAVITY_NORTH | GRAVITY_NORTHEAST |
| GRAVITY_WEST | GRAVITY_CENTER | GRAVITY_EAST |
| GRAVITY_SOUTHWEST | GRAVITY_SOUTH | GRAVITY_SOUTHEAST |
Названия задают ориентир, но конкретное использование и допустимые смещения определяет операция. В горизонтальном append одинаковая ширина не меняет смысл, а разная высота делает вертикальное выравнивание видимым. Примеры используют имена; числа1/5/8 в stdout — наблюдения установленной версии, а не рекомендация запоминать номера.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagegravity">
<refnamediv>
<refname>Imagick::getImageGravity</refname>
<refpurpose>Gets the image gravity</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>int</type><methodname>Imagick::getImageGravity</methodname>
<void />
</methodsynopsis>
<para>
Gets the current gravity value of the
image. Unlike <function>Imagick::getGravity</function>, this method
returns the gravity defined for the current image sequence.
&imagick.method.available.0x644;
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns the images gravity property. Refer to the list of
<link linkend="imagick.constants.gravity">gravity constants</link>.
</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
-->
Прочитать свойство текущего изображения
У собственного исходника прочитан int0 — наблюдаемое незаданное Core-значение этого известного исходника. Это значение свойства, не координата и не код неудачи чтения. Само чтение не меняет рисунок.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
$image=new Imagick(__DIR__.'/source.png');
$value=$image->getImageGravity();
$undefined=$value===0; // Observed unset Core value of this known own source.
printf("gravity=%d type=%s undefined=%d\n",$value,get_debug_type($value),(int)$undefined);
gravityView($image,'gravity-get-minimal.png');
gravityDiagnostic('image-gravity-getimagegravity-minimal',['value'=>$value,'value_type'=>get_debug_type($value),'undefined'=>$undefined,'pixels'=>gravityPixels($image),'checks'=>['getter_is_int'=>is_int($value),'known_own_source_is_undefined'=>$undefined]]);
echo "gravity-get-minimal.png\nmetrics.json\n";
У собственного исходника прочитан int0 — наблюдаемое незаданное Core-значение этого известного исходника. Это значение свойства, не координата и не код неудачи чтения. Само чтение не меняет рисунок. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity=0 type=int undefined=1
gravity-get-minimal.png
metrics.json
Практическая задача getter — проверить настройки выбранного кадра, когда входом служит последовательность. В следующем примере два холста имеют разные imagegravity, а общий Wand-option равен Center. setIteratorIndex выбирает0 или1; getImage извлекает только текущий кадр. Значение getter явно передаётся compositeImageGravity третьим аргументом. Этот метод не доказательство автоматического чтения свойства: связь видна в самом выражении.
Прочитать разные кадры и явно передать положение операции
Getter читает выбранный кадр последовательности. Его значение явно передано compositeImageGravity, поэтому получены две разные позиции. getGravity контекста остаётся Center и не заменяет настройки кадров.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
[, $tile]=gravityParts();$sequence=new Imagick();
foreach([Imagick::GRAVITY_NORTHWEST,Imagick::GRAVITY_SOUTH] as $value){$canvas=new Imagick();$canvas->newImage(400,320,'white');$canvas->setImageGravity($value);$sequence->addImage($canvas);}
$sequence->setGravity(Imagick::GRAVITY_CENTER); // A different setting: this does not rewrite existing frames.
$views=[];$observed=[];
foreach(['north','south'] as $index=>$name){
$sequence->setIteratorIndex($index);$frameGravity=$sequence->getImageGravity();$wandGravity=$sequence->getGravity();
$canvas=$sequence->getImage(); // Extract the current image, not a clone of the whole sequence.
$ok=$canvas->compositeImageGravity($tile,Imagick::COMPOSITE_OVER,$frameGravity); // Explicit argument bridges the getter to this operation.
gravityView($canvas,$name.'-bridge.png');$views[]=new Imagick(__DIR__.'/'.$name.'-bridge.png');
$observed[]=['index'=>$index,'image_gravity'=>$frameGravity,'wand_gravity'=>$wandGravity,'composite_return'=>$ok];
}
$sequence->setFirstIterator();$rects=gravityCompare($views,'gravity-get-workflow.png');
gravityDiagnostic('image-gravity-getimagegravity-workflow',['frames'=>$observed,'panel_geometry'=>$rects,'checks'=>['current_frames_have_distinct_gravity'=>array_column($observed,'image_gravity')===[Imagick::GRAVITY_NORTHWEST,Imagick::GRAVITY_SOUTH],'wand_option_is_separate'=>array_column($observed,'wand_gravity')===[Imagick::GRAVITY_CENTER,Imagick::GRAVITY_CENTER],'explicit_placements_differ'=>gravityHash($views[0])!==gravityHash($views[1]),'bridge_succeeded'=>!in_array(false,array_column($observed,'composite_return'),true)]]);
echo "gravity-get-workflow.png\nnorth-bridge.png\nsouth-bridge.png\nmetrics.json\nframes=2 distinct-image-gravity=1 wand-option-is-separate=1\n";
Getter читает выбранный кадр последовательности. Его значение явно передано compositeImageGravity, поэтому получены две разные позиции. getGravity контекста остаётся Center и не заменяет настройки кадров. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity-get-workflow.png
north-bridge.png
south-bridge.png
metrics.json
frames=2 distinct-image-gravity=1 wand-option-is-separate=1
Задать правило нужному кадру, затем вызвать настоящий consumer

Gravity здесь означает правило привязки: сверху, по центру или снизу; это не сила тяжести и не готовая пара x/y. У объекта есть текущее изображение, а в последовательности текущий кадр выбирает iterator. $image — переменная с объектом; -> вызывает метод, () содержит аргументы, ; завершает инструкцию. Imagick::GRAVITY_SOUTH — именованная целочисленная константа. Getter получает значение без аргументов; setter записывает одно значение. Переменные, объекты и последовательности Imagick — связанные объяснения.
Минимальная запись и полный официальный контракт
Imagick::setImageGravity(int $gravity): bool$ok = $image->setImageGravity(Imagick::GRAVITY_SOUTH);| Аргумент/результат | Смысл |
|---|---|
| $gravity:int, обязательный | Именованная константа положения текущего изображения. Не x/y и не номер кадра. |
| booltrue | Фактический статус успешной записи свойства в PHP binding. |
| Пиксели | Setter сам не изменяет размеры, компоненты и положение рисунка. |
В полном официальном XML и текущей странице есть неточность: synopsis обещает bool, а абзац Return Values говорит, что значение не возвращается. Текущий stub и PHP wrapper возвращают true; оригинальный абзац ниже сохранён. Exact Wand просто присваивает image->gravity и не проверяет принадлежность int перечислению. В приложении разрешайте именованные варианты по своей таблице, не произвольные номера. Успех setter не означает, что следующая произвольная операция читает это свойство.
Доступность: PECL imagick 2 >= 2.3.0, PECL imagick 3; оба метода требуют сборку с ImageMagick6.4.4 или новее. В исходных официальных записях нет примеров кода и отдельного раздела ошибок. Текущий PHP wrapper проверяет непустой Imagick: без изображения оба метода дают ImagickException; неверный путь может завершиться исключением ещё в new Imagick, до getter/setter. Неверный PHP-тип/число аргументов обрабатывает PHP binding. Это уточнение фактического поведения, а не выдуманный текст официальной страницы.
Именованные положения
| Слева | По центру | Справа |
|---|---|---|
| GRAVITY_NORTHWEST | GRAVITY_NORTH | GRAVITY_NORTHEAST |
| GRAVITY_WEST | GRAVITY_CENTER | GRAVITY_EAST |
| GRAVITY_SOUTHWEST | GRAVITY_SOUTH | GRAVITY_SOUTHEAST |
Названия задают ориентир, но конкретное использование и допустимые смещения определяет операция. В горизонтальном append одинаковая ширина не меняет смысл, а разная высота делает вертикальное выравнивание видимым. Примеры используют имена; числа1/5/8 в stdout — наблюдения установленной версии, а не рекомендация запоминать номера.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagegravity">
<refnamediv>
<refname>Imagick::setImageGravity</refname>
<refpurpose>Sets the image gravity</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageGravity</methodname>
<methodparam><type>int</type><parameter>gravity</parameter></methodparam>
</methodsynopsis>
<para>
Sets the gravity property for the current image. This method can be used
to set the gravity property for a single image sequence.
&imagick.method.available.0x644;
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>gravity</parameter></term>
<listitem>
<para>
The gravity property. Refer to the list of
<link linkend="imagick.constants.gravity">gravity constants</link>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.void;
</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 возвращает booltrue, getter читает South (8 в этой сборке), а RGBA8-компоненты до и после совпадают. Нужна следующая операция, которая использует это свойство.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
$image=new Imagick(__DIR__.'/source.png');$before=gravityHash($image);
$ok=$image->setImageGravity(Imagick::GRAVITY_SOUTH);
$value=$image->getImageGravity();$same=$before===gravityHash($image);
printf("set=%s gravity=%d pixels_unchanged=%d\n",$ok?'true':'false',$value,(int)$same);
gravityView($image,'gravity-set-minimal.png');
gravityDiagnostic('image-gravity-setimagegravity-minimal',['return_value'=>$ok,'return_type'=>get_debug_type($ok),'value'=>$value,'before_hash'=>$before,'after_hash'=>gravityHash($image),'checks'=>['setter_true'=>$ok===true,'property_is_south'=>$value===Imagick::GRAVITY_SOUTH,'pixels_unchanged'=>$same]]);
echo "gravity-set-minimal.png\nmetrics.json\n";
Успешный setter возвращает booltrue, getter читает South (8 в этой сборке), а RGBA8-компоненты до и после совпадают. Нужна следующая операция, которая использует это свойство. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
set=true gravity=8 pixels_unchanged=1
gravity-set-minimal.png
metrics.json
При росте требования макет получает строковую настройку top/middle/bottom. Нельзя считать произвольный int от посетителя безопасной поддерживаемой константой: таблица приложения разрешает три понятных варианта. Сначала показана типичная ошибка — setGravity у Wand и ожидание изменения кадров. Затем политика применяется к конкретному короткому кадру. Последние две панели объясняют ещё одну частую ошибку: compositeImage получает явные10,20 и при разных imagegravity рисует в том же месте.
Применить настройку карточки к нужному кадру
Строковая настройка bottom проверена по разрешённым значениям и применена к короткому кадру. Append теперь ставит его снизу. Два отдельных compositeImage с одинаковыми x/y совпадают: координатный метод не превращается в gravity-операцию от одного setter.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
[$tall,$tile]=gravityParts();$policy='bottom';
$allowed=['top'=>Imagick::GRAVITY_NORTHWEST,'middle'=>Imagick::GRAVITY_CENTER,'bottom'=>Imagick::GRAVITY_SOUTH];
if(!array_key_exists($policy,$allowed)){throw new InvalidArgumentException('Unknown card alignment');}$wanted=$allowed[$policy];
$wrong=new Imagick();$wrong->setGravity($wanted);$wrong->addImage($tall);$wrong->addImage($tile);$wrong->setFirstIterator();$wrong->setImageBackgroundColor('white');
$wrong->setIteratorIndex(1);$wrongFrame=$wrong->getImageGravity();$wrong->setFirstIterator();$wrongResult=$wrong->appendImages(false);gravityView($wrongResult,'wand-option-only.png');
$correct=new Imagick();$correct->addImage($tall);$correct->addImage($tile);$correct->setFirstIterator();$correct->setImageGravity(Imagick::GRAVITY_NORTHWEST);
$correct->setIteratorIndex(1);$before=gravityHash($correct);$ok=$correct->setImageGravity($wanted);$selected=$correct->getImageGravity();$same=$before===gravityHash($correct);
$correct->setFirstIterator();$correct->setImageBackgroundColor('white');$result=$correct->appendImages(false);gravityView($result,'frame-policy-applied.png');
$views=[new Imagick(__DIR__.'/wand-option-only.png'),new Imagick(__DIR__.'/frame-policy-applied.png')];$xy=[];
foreach(['north'=>Imagick::GRAVITY_NORTHWEST,'south'=>Imagick::GRAVITY_SOUTH] as $name=>$value){
$canvas=new Imagick();$canvas->newImage(400,320,'white');$canvas->setImageGravity($value);
$canvas->compositeImage($tile,Imagick::COMPOSITE_OVER,10,20); // Absolute x/y: no image-gravity lookup here.
gravityView($canvas,'xy-'.$name.'.png');$xy[]=new Imagick(__DIR__.'/xy-'.$name.'.png');$views[]=end($xy);
}
$rects=gravityCompare($views,'gravity-set-workflow.png');$appendChanged=gravityHash($views[0])!==gravityHash($views[1]);$xySame=gravityHash($xy[0])===gravityHash($xy[1]);
gravityDiagnostic('image-gravity-setimagegravity-workflow',['policy'=>$policy,'wanted'=>$wanted,'wrong_wand_gravity'=>$wrong->getGravity(),'wrong_frame_gravity'=>$wrongFrame,'selected_frame_gravity'=>$selected,'setter_return'=>$ok,'setter_pixels_unchanged'=>$same,'append_changed'=>$appendChanged,'absolute_xy_unchanged'=>$xySame,'xy'=>['x'=>10,'y'=>20],'panel_geometry'=>$rects,'checks'=>['named_policy_matches_frame'=>$selected===$wanted,'wand_option_did_not_rewrite_frame'=>$wrongFrame!==$wanted,'absolute_xy_is_unchanged_by_image_gravity'=>$xySame,'setter_true_and_pixels_unchanged'=>$ok===true&&$same]]);
echo "gravity-set-workflow.png\nwand-option-only.png\nframe-policy-applied.png\nxy-north.png\nxy-south.png\nmetrics.json\n";
printf("policy=%s append-changes=%d absolute-xy-unchanged=%d\n",$policy,(int)$appendChanged,(int)$xySame);
Строковая настройка bottom проверена по разрешённым значениям и применена к короткому кадру. Append теперь ставит его снизу. Два отдельных compositeImage с одинаковыми x/y совпадают: координатный метод не превращается в gravity-операцию от одного setter. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity-set-workflow.png
wand-option-only.png
frame-policy-applied.png
xy-north.png
xy-south.png
metrics.json
policy=bottom append-changes=1 absolute-xy-unchanged=1
Выбрать операцию и проверить границы поведения
Названия gravity общие, а путь применения зависит от API. Командная строка magick может разобрать -gravity вместе с -extent/-geometry до Core-вызова; нельзя механически переносить это поведение в PHP. В проверенной Imagick3.8.1/ImageMagick7.1.1-46 extentImage(w,h,x,y) использует явные -x/-y в Core и не читает imagegravity: NW и South при одинаковых0,0 дали один растр. Для собственного расширенного холста рассчитывайте нужные смещения по контракту extentImage либо создайте canvas и явно передайте gravity в compositeImageGravity. Не обещаем одно поведение всех версий и всех методов.
| Потребность | Подход |
|---|---|
| Выстроить карточки разной высоты рядом | Задать imagegravity нужным кадрам, выбрать начало и вызвать appendImages(false) |
| Поставить одно превью по якорю на холст | Явно передать константу или результат getter в compositeImageGravity |
| Поставить watermark на точные координаты | Вычислить x/y и передать в compositeImage; gravity не добавляет отступы сам |
| Позиционировать текст | Настроить ImagickDraw и его gravity; учитывать метрики шрифта и baseline |
| Обработать всю последовательность | Явно пройти/выбрать кадры; текущий кадр и текущая последовательность не взаимозаменяемы |
| Сохранить прозрачность или цвет | Проверять отдельный контракт alpha/цвета; gravity не является преобразованием ICC и не гарантирует alpha-политику |
Упражнение: измените $policy с bottom на уже разрешённый вариант middle и убедитесь, что короткая картинка располагается на y=80, а setter по-прежнему не меняет её компоненты. Решение — связать middle с GRAVITY_CENTER, задать это второму кадру, вернуть iterator к началу и выполнить append. При одинаковой высоте кадров различия top/middle/bottom могут стать невидимыми: это геометрия задачи, не доказательство поломки setter. Измерять скорость в этих примерах мы не пытаемся; стоимость чтения свойства и создания нового растрового холста — разные виды работы.
Полный helper подготовки и просмотра
<?php
declare(strict_types=1);
function gravityRestore():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 gravityHash(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 gravityPixels(Imagick $image):array {return ['width'=>$image->getImageWidth(),'height'=>$image->getImageHeight(),'RGBA8_hash'=>gravityHash($image)];}
function gravityOpaque(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 gravityView(Imagick $image,string $filename):void {$view=gravityOpaque($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 gravityParts():array {
$source=new Imagick(__DIR__.'/source.png');$tile=new Imagick();$tile->newImage(400,320,'white');$tile->compositeImage($source,Imagick::COMPOSITE_OVER,0,0);$tile->resizeImage(200,160,Imagick::FILTER_LANCZOS,1);$tile->setImagePage(0,0,0,0);
$d=new ImagickDraw();$d->setFillColor('none');$d->setStrokeColor('#c66d32');$d->setStrokeWidth(1);$d->rectangle(0,0,199,159);$tile->drawImage($d);
$tall=new Imagick();$tall->newImage(200,320,'#e2f1ed');$tall->compositeImage($tile,Imagick::COMPOSITE_OVER,0,0);
$d=new ImagickDraw();$d->setStrokeColor('none');$d->setFillColor('#195b63');$d->roundRectangle(16,186,184,212,5,5);$d->setFillColor('#6b9093');$d->rectangle(16,230,160,240);$d->rectangle(16,250,130,260);$d->setFillColor('#d09443');$d->roundRectangle(16,278,100,304,4,4);$tall->drawImage($d);
return [$tall,$tile];
}
function gravityCompare(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];}gravityView($board,$filename);return $rects;}
function gravityDiagnostic(string $id,array $data):void {$doc=['schema'=>'aen-image-gravity-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');}}
gravityParts готовит только собственный макет; target getter/setter и append/bridge вызываются в программах. Нейтральные RGB8-превью показаны OVERwhite, поэтому они не сертифицируют сохранение прозрачности исходного RGBA во всех форматах. В веб-проекте отдавайте созданный PNG отдельным ответом с Content-Type:image/png, без echo диагностики перед бинарными байтами. Следующие шаги: кадры и iterator, композиция, текст и Draw gravity, работа с файлами.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::getImageGravityGravity текущего кадра: чтение
PECL imagick 2 >= 2.3.0, PECL imagick 3 · imagick
Imagick::getImageGravity(): intGravity здесь означает правило привязки: сверху, по центру или снизу; это не сила тяжести и не готовая пара x/y. У объекта есть текущее изображение, а в последовательности текущий кадр выбирает iterator. $image — переменная с объектом; -> вызывает метод, () содержит аргументы, ; завершает инструкцию. Imagick::GRAVITY_SOUTH — именованная целочисленная константа. Getter получает значение без аргументов; setter записывает одно значение. Переменные, объекты и последовательности Imagick — связанные объяснения.
Минимальная запись и полный официальный контракт
Imagick::getImageGravity(): int$gravity = $image->getImageGravity();Параметров нет; возвращается int — gravity текущего изображения, одна из констант семейства GRAVITY_*. Официальная запись отличает метод от getGravity и говорит о текущей последовательности. Exact C уточняет: читается image->gravity именно текущего кадра, не общий результат всех кадров. Если выбрать другой кадр, число может измениться. У этого известного собственного исходника наблюдается незаданное Core-значение0; не трактуйте0 как координату или универсальный код ошибки.
Доступность: PECL imagick 2 >= 2.3.0, PECL imagick 3; оба метода требуют сборку с ImageMagick6.4.4 или новее. В исходных официальных записях нет примеров кода и отдельного раздела ошибок. Текущий PHP wrapper проверяет непустой Imagick: без изображения оба метода дают ImagickException; неверный путь может завершиться исключением ещё в new Imagick, до getter/setter. Неверный PHP-тип/число аргументов обрабатывает PHP binding. Это уточнение фактического поведения, а не выдуманный текст официальной страницы.
Именованные положения
| Слева | По центру | Справа |
|---|---|---|
| GRAVITY_NORTHWEST | GRAVITY_NORTH | GRAVITY_NORTHEAST |
| GRAVITY_WEST | GRAVITY_CENTER | GRAVITY_EAST |
| GRAVITY_SOUTHWEST | GRAVITY_SOUTH | GRAVITY_SOUTHEAST |
Названия задают ориентир, но конкретное использование и допустимые смещения определяет операция. В горизонтальном append одинаковая ширина не меняет смысл, а разная высота делает вертикальное выравнивание видимым. Примеры используют имена; числа1/5/8 в stdout — наблюдения установленной версии, а не рекомендация запоминать номера.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagegravity">
<refnamediv>
<refname>Imagick::getImageGravity</refname>
<refpurpose>Gets the image gravity</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>int</type><methodname>Imagick::getImageGravity</methodname>
<void />
</methodsynopsis>
<para>
Gets the current gravity value of the
image. Unlike <function>Imagick::getGravity</function>, this method
returns the gravity defined for the current image sequence.
&imagick.method.available.0x644;
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns the images gravity property. Refer to the list of
<link linkend="imagick.constants.gravity">gravity constants</link>.
</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
-->
Прочитать свойство текущего изображения
У собственного исходника прочитан int0 — наблюдаемое незаданное Core-значение этого известного исходника. Это значение свойства, не координата и не код неудачи чтения. Само чтение не меняет рисунок.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
$image=new Imagick(__DIR__.'/source.png');
$value=$image->getImageGravity();
$undefined=$value===0; // Observed unset Core value of this known own source.
printf("gravity=%d type=%s undefined=%d\n",$value,get_debug_type($value),(int)$undefined);
gravityView($image,'gravity-get-minimal.png');
gravityDiagnostic('image-gravity-getimagegravity-minimal',['value'=>$value,'value_type'=>get_debug_type($value),'undefined'=>$undefined,'pixels'=>gravityPixels($image),'checks'=>['getter_is_int'=>is_int($value),'known_own_source_is_undefined'=>$undefined]]);
echo "gravity-get-minimal.png\nmetrics.json\n";
У собственного исходника прочитан int0 — наблюдаемое незаданное Core-значение этого известного исходника. Это значение свойства, не координата и не код неудачи чтения. Само чтение не меняет рисунок. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity=0 type=int undefined=1
gravity-get-minimal.png
metrics.json
Прочитать разные кадры и явно передать положение операции
Getter читает выбранный кадр последовательности. Его значение явно передано compositeImageGravity, поэтому получены две разные позиции. getGravity контекста остаётся Center и не заменяет настройки кадров.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
[, $tile]=gravityParts();$sequence=new Imagick();
foreach([Imagick::GRAVITY_NORTHWEST,Imagick::GRAVITY_SOUTH] as $value){$canvas=new Imagick();$canvas->newImage(400,320,'white');$canvas->setImageGravity($value);$sequence->addImage($canvas);}
$sequence->setGravity(Imagick::GRAVITY_CENTER); // A different setting: this does not rewrite existing frames.
$views=[];$observed=[];
foreach(['north','south'] as $index=>$name){
$sequence->setIteratorIndex($index);$frameGravity=$sequence->getImageGravity();$wandGravity=$sequence->getGravity();
$canvas=$sequence->getImage(); // Extract the current image, not a clone of the whole sequence.
$ok=$canvas->compositeImageGravity($tile,Imagick::COMPOSITE_OVER,$frameGravity); // Explicit argument bridges the getter to this operation.
gravityView($canvas,$name.'-bridge.png');$views[]=new Imagick(__DIR__.'/'.$name.'-bridge.png');
$observed[]=['index'=>$index,'image_gravity'=>$frameGravity,'wand_gravity'=>$wandGravity,'composite_return'=>$ok];
}
$sequence->setFirstIterator();$rects=gravityCompare($views,'gravity-get-workflow.png');
gravityDiagnostic('image-gravity-getimagegravity-workflow',['frames'=>$observed,'panel_geometry'=>$rects,'checks'=>['current_frames_have_distinct_gravity'=>array_column($observed,'image_gravity')===[Imagick::GRAVITY_NORTHWEST,Imagick::GRAVITY_SOUTH],'wand_option_is_separate'=>array_column($observed,'wand_gravity')===[Imagick::GRAVITY_CENTER,Imagick::GRAVITY_CENTER],'explicit_placements_differ'=>gravityHash($views[0])!==gravityHash($views[1]),'bridge_succeeded'=>!in_array(false,array_column($observed,'composite_return'),true)]]);
echo "gravity-get-workflow.png\nnorth-bridge.png\nsouth-bridge.png\nmetrics.json\nframes=2 distinct-image-gravity=1 wand-option-is-separate=1\n";
Getter читает выбранный кадр последовательности. Его значение явно передано compositeImageGravity, поэтому получены две разные позиции. getGravity контекста остаётся Center и не заменяет настройки кадров. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity-get-workflow.png
north-bridge.png
south-bridge.png
metrics.json
frames=2 distinct-image-gravity=1 wand-option-is-separate=1
Imagick::setImageGravityGravity текущего кадра: запись
PECL imagick 2 >= 2.3.0, PECL imagick 3 · imagick
Imagick::setImageGravity(int $gravity): boolGravity здесь означает правило привязки: сверху, по центру или снизу; это не сила тяжести и не готовая пара x/y. У объекта есть текущее изображение, а в последовательности текущий кадр выбирает iterator. $image — переменная с объектом; -> вызывает метод, () содержит аргументы, ; завершает инструкцию. Imagick::GRAVITY_SOUTH — именованная целочисленная константа. Getter получает значение без аргументов; setter записывает одно значение. Переменные, объекты и последовательности Imagick — связанные объяснения.
Минимальная запись и полный официальный контракт
Imagick::setImageGravity(int $gravity): bool$ok = $image->setImageGravity(Imagick::GRAVITY_SOUTH);| Аргумент/результат | Смысл |
|---|---|
| $gravity:int, обязательный | Именованная константа положения текущего изображения. Не x/y и не номер кадра. |
| booltrue | Фактический статус успешной записи свойства в PHP binding. |
| Пиксели | Setter сам не изменяет размеры, компоненты и положение рисунка. |
В полном официальном XML и текущей странице есть неточность: synopsis обещает bool, а абзац Return Values говорит, что значение не возвращается. Текущий stub и PHP wrapper возвращают true; оригинальный абзац ниже сохранён. Exact Wand просто присваивает image->gravity и не проверяет принадлежность int перечислению. В приложении разрешайте именованные варианты по своей таблице, не произвольные номера. Успех setter не означает, что следующая произвольная операция читает это свойство.
Доступность: PECL imagick 2 >= 2.3.0, PECL imagick 3; оба метода требуют сборку с ImageMagick6.4.4 или новее. В исходных официальных записях нет примеров кода и отдельного раздела ошибок. Текущий PHP wrapper проверяет непустой Imagick: без изображения оба метода дают ImagickException; неверный путь может завершиться исключением ещё в new Imagick, до getter/setter. Неверный PHP-тип/число аргументов обрабатывает PHP binding. Это уточнение фактического поведения, а не выдуманный текст официальной страницы.
Именованные положения
| Слева | По центру | Справа |
|---|---|---|
| GRAVITY_NORTHWEST | GRAVITY_NORTH | GRAVITY_NORTHEAST |
| GRAVITY_WEST | GRAVITY_CENTER | GRAVITY_EAST |
| GRAVITY_SOUTHWEST | GRAVITY_SOUTH | GRAVITY_SOUTHEAST |
Названия задают ориентир, но конкретное использование и допустимые смещения определяет операция. В горизонтальном append одинаковая ширина не меняет смысл, а разная высота делает вертикальное выравнивание видимым. Примеры используют имена; числа1/5/8 в stdout — наблюдения установленной версии, а не рекомендация запоминать номера.
Полный официальный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagegravity">
<refnamediv>
<refname>Imagick::setImageGravity</refname>
<refpurpose>Sets the image gravity</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageGravity</methodname>
<methodparam><type>int</type><parameter>gravity</parameter></methodparam>
</methodsynopsis>
<para>
Sets the gravity property for the current image. This method can be used
to set the gravity property for a single image sequence.
&imagick.method.available.0x644;
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>gravity</parameter></term>
<listitem>
<para>
The gravity property. Refer to the list of
<link linkend="imagick.constants.gravity">gravity constants</link>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.void;
</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 возвращает booltrue, getter читает South (8 в этой сборке), а RGBA8-компоненты до и после совпадают. Нужна следующая операция, которая использует это свойство.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
$image=new Imagick(__DIR__.'/source.png');$before=gravityHash($image);
$ok=$image->setImageGravity(Imagick::GRAVITY_SOUTH);
$value=$image->getImageGravity();$same=$before===gravityHash($image);
printf("set=%s gravity=%d pixels_unchanged=%d\n",$ok?'true':'false',$value,(int)$same);
gravityView($image,'gravity-set-minimal.png');
gravityDiagnostic('image-gravity-setimagegravity-minimal',['return_value'=>$ok,'return_type'=>get_debug_type($ok),'value'=>$value,'before_hash'=>$before,'after_hash'=>gravityHash($image),'checks'=>['setter_true'=>$ok===true,'property_is_south'=>$value===Imagick::GRAVITY_SOUTH,'pixels_unchanged'=>$same]]);
echo "gravity-set-minimal.png\nmetrics.json\n";
Успешный setter возвращает booltrue, getter читает South (8 в этой сборке), а RGBA8-компоненты до и после совпадают. Нужна следующая операция, которая использует это свойство. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
set=true gravity=8 pixels_unchanged=1
gravity-set-minimal.png
metrics.json
Применить настройку карточки к нужному кадру
Строковая настройка bottom проверена по разрешённым значениям и применена к короткому кадру. Append теперь ставит его снизу. Два отдельных compositeImage с одинаковыми x/y совпадают: координатный метод не превращается в gravity-операцию от одного setter.
<?php
declare(strict_types=1);
require __DIR__.'/gravity-fixture.php';
gravityRestore();
[$tall,$tile]=gravityParts();$policy='bottom';
$allowed=['top'=>Imagick::GRAVITY_NORTHWEST,'middle'=>Imagick::GRAVITY_CENTER,'bottom'=>Imagick::GRAVITY_SOUTH];
if(!array_key_exists($policy,$allowed)){throw new InvalidArgumentException('Unknown card alignment');}$wanted=$allowed[$policy];
$wrong=new Imagick();$wrong->setGravity($wanted);$wrong->addImage($tall);$wrong->addImage($tile);$wrong->setFirstIterator();$wrong->setImageBackgroundColor('white');
$wrong->setIteratorIndex(1);$wrongFrame=$wrong->getImageGravity();$wrong->setFirstIterator();$wrongResult=$wrong->appendImages(false);gravityView($wrongResult,'wand-option-only.png');
$correct=new Imagick();$correct->addImage($tall);$correct->addImage($tile);$correct->setFirstIterator();$correct->setImageGravity(Imagick::GRAVITY_NORTHWEST);
$correct->setIteratorIndex(1);$before=gravityHash($correct);$ok=$correct->setImageGravity($wanted);$selected=$correct->getImageGravity();$same=$before===gravityHash($correct);
$correct->setFirstIterator();$correct->setImageBackgroundColor('white');$result=$correct->appendImages(false);gravityView($result,'frame-policy-applied.png');
$views=[new Imagick(__DIR__.'/wand-option-only.png'),new Imagick(__DIR__.'/frame-policy-applied.png')];$xy=[];
foreach(['north'=>Imagick::GRAVITY_NORTHWEST,'south'=>Imagick::GRAVITY_SOUTH] as $name=>$value){
$canvas=new Imagick();$canvas->newImage(400,320,'white');$canvas->setImageGravity($value);
$canvas->compositeImage($tile,Imagick::COMPOSITE_OVER,10,20); // Absolute x/y: no image-gravity lookup here.
gravityView($canvas,'xy-'.$name.'.png');$xy[]=new Imagick(__DIR__.'/xy-'.$name.'.png');$views[]=end($xy);
}
$rects=gravityCompare($views,'gravity-set-workflow.png');$appendChanged=gravityHash($views[0])!==gravityHash($views[1]);$xySame=gravityHash($xy[0])===gravityHash($xy[1]);
gravityDiagnostic('image-gravity-setimagegravity-workflow',['policy'=>$policy,'wanted'=>$wanted,'wrong_wand_gravity'=>$wrong->getGravity(),'wrong_frame_gravity'=>$wrongFrame,'selected_frame_gravity'=>$selected,'setter_return'=>$ok,'setter_pixels_unchanged'=>$same,'append_changed'=>$appendChanged,'absolute_xy_unchanged'=>$xySame,'xy'=>['x'=>10,'y'=>20],'panel_geometry'=>$rects,'checks'=>['named_policy_matches_frame'=>$selected===$wanted,'wand_option_did_not_rewrite_frame'=>$wrongFrame!==$wanted,'absolute_xy_is_unchanged_by_image_gravity'=>$xySame,'setter_true_and_pixels_unchanged'=>$ok===true&&$same]]);
echo "gravity-set-workflow.png\nwand-option-only.png\nframe-policy-applied.png\nxy-north.png\nxy-south.png\nmetrics.json\n";
printf("policy=%s append-changes=%d absolute-xy-unchanged=%d\n",$policy,(int)$appendChanged,(int)$xySame);
Строковая настройка bottom проверена по разрешённым значениям и применена к короткому кадру. Append теперь ставит его снизу. Два отдельных compositeImage с одинаковыми x/y совпадают: координатный метод не превращается в gravity-операцию от одного setter. Сохраните example.php и два дополнительных текстовых файла из архива в одной папке; запустите php example.php с Imagick/PNG и правом записи. Helper проверяет SHA и восстанавливает свой исходник, готовит компоненты карточек, сохраняет нейтральные RGB8-просмотры и metrics.json. Изучаемые getter/setter, выбор текущего кадра и операции размещения видимы в программе.
Ожидаемый вывод
gravity-set-workflow.png
wand-option-only.png
frame-policy-applied.png
xy-north.png
xy-south.png
metrics.json
policy=bottom append-changes=1 absolute-xy-unchanged=1
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


