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

Дерево руководства
Глава 370 · После объектов, пикселей, alpha и файлов
Imagick: правильная ориентация и подпись пикселей
Сохранить прямую PNG-карточку с alpha, различить метку и физический поворот, сравнить поток пикселей отдельно от SHA файла.
Получить самостоятельную карточку в правильном направлении
Фотография пришла боком, хотя просмотрщик показывал её прямо. Для карточки сайта нужен самостоятельный файл с правильно расположенными пикселями: направление не должно зависеть от того, учитывает ли программа метку. Наш собственный PNG хранит асимметричную карточку 400 × 320 с указанием RIGHTTOP. После нормализации получаем 320 × 400 с читаемым текстом и прозрачным окном.


Понятия до схемы
Растр — сетка пикселей. Ширина W и высота H измеряются в пикселях; x растёт вправо, y вниз от верхнего левого угла. RGB — красная, зелёная и синяя компоненты, RGBA добавляет alpha: 0 пропускает фон, 1 полностью закрывает его. OVER накладывает этот слой на непрозрачную подложку только для просмотра. Нейтральный просмотр создаётся на новом холсте и не копирует метку: на первой панели видны именно хранимые пиксели. Буквы A/B/C/D, стрелка и текст — часть нашего исходного рисунка, не автоматически измеренные свойства.
Метка ориентации — отдельное указание, как показывать сетку. EXIF — один из способов хранить метаданные; в исходном PNG метка действительно записана в eXIf, а после записи библиотека также может использовать собственную запись PNG. Мы проверяем фактическое повторное чтение, не предполагаем одинаковое поведение всех просмотрщиков. Подпись пикселей — контрольная строка по их данным. SHA-256 — алгоритм хеширования: результат здесь записан 64 шестнадцатеричными символами, то есть цифрами 0–9 и буквами a–f. SHA файла охватывает все его байты, включая служебные записи; подпись текущего изображения вычисляется отдельно.

Самая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$orientation = $image->getImageOrientation();
echo $orientation;Пустые скобки означают отсутствие аргументов. Для нашего входа прочитано RIGHTTOP, в этой сборке код 6. Getter читает указание, не распознаёт верх фотографии по содержимому и не поворачивает пиксели. ORIENTATION_UNDEFINED сообщает, что надёжного указания нет; код 0 не является bool false.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.
Для реального исправления используем autoOrient(): в проверенной Imagick 3.8.1 это контекстный метод без аргументов, который меняет текущую картинку и не возвращает bool или новый объект. Он доступен в исходнике при ImageMagick ≥ 6.9.2; на другой установке проверьте method_exists. Он выполняет нужное отражение/поворот по метке и выставляет TOPLEFT. Это не распознавание горизонта и не самостоятельный новый узел официального справочника. Не пишите $upright = $upright->autoOrient().
$upright = clone $image;
$upright->autoOrient();
$upright->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);Перед полной программой: $signatureBefore = $image->getImageSignature(); сохраняет контрольную строку до поворота, чтобы сравнить её с результатом. setImageOrientation(TOPLEFT) после autoOrient явно назначает обычное положение уже исправленному растру и возвращает bool-статус. <?php открывает PHP, declare(strict_types=1) включает строгие типы аргументов, require подключает открытый helper. new Imagick читает файл. Запись сохраняет PNG с восемью битами на компоненту, затем новый объект читает файл заново. Массив [$a, $b] объединяет панели; [] не поворачивает картинку. Проверка !== ниже сравнивает контрольные строки на различие. Изменение порядка пикселей меняет подпись на нашем асимметричном входе.
Сохранить правильно повёрнутую карточку с прозрачным окном
Самостоятельный upright.png имеет размер 320 × 400 и метку TOPLEFT. Текст читается прямо, окно остаётся прозрачным; два просмотра получены после чтения именно сохранённого PNG. Исходные пиксели 400 × 320 на первой панели показаны без автоматического поворота просмотрщиком.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$before = $source->getImageOrientation();
$signatureBefore = $source->getImageSignature();
$upright = clone $source;
$upright->autoOrient();
$upright->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
saveOrientationPNG($upright, 'upright.png', true);
$read = new Imagick(__DIR__ . '/upright.png');
$white = orientationPreview($read); $dark = orientationPreview($read, '#243c4d');
saveOrientationPNG($sourceWhite, 'source-preview8.png');
saveOrientationPNG($white, 'upright-white.png'); saveOrientationPNG($dark, 'upright-dark.png');
saveOrientationComparison([$sourceWhite, $white, $dark], 'orientation-first.png');
echo "orientation-first.png\nupright.png\nsource-preview8.png\nupright-white.png\nupright-dark.png\n";
printf("orientation=%d->%d size=%dx%d alpha=%d signature-changed=%d\n", $before, $read->getImageOrientation(), $read->getImageWidth(), $read->getImageHeight(), (int)$read->getImageAlphaChannel(), (int)($signatureBefore !== $read->getImageSignature()));
Самостоятельный upright.png имеет размер 320 × 400 и метку TOPLEFT. Текст читается прямо, окно остаётся прозрачным; два просмотра получены после чтения именно сохранённого PNG. Исходные пиксели 400 × 320 на первой панели показаны без автоматического поворота просмотрщиком. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-first.png
upright.png
source-preview8.png
upright-white.png
upright-dark.png
orientation=6->1 size=320x400 alpha=1 signature-changed=1
Разделить назначение метки и перестановку пикселей
Самая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$ok = $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);TOPLEFT говорит: пиксели уже стоят обычно. Делайте такое назначение, когда их происхождение известно, например сразу после физической нормализации. Метод возвращает true при успехе; результат изображения остаётся в $image. Если исходный растр лежит боком, одна эта строка не исправит его. Неверная метка может заставить другую программу показать его иначе.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.

Увидеть, почему одна метка TOPLEFT не исправляет повёрнутый растр
Средняя панель остаётся боком: setter поменял только указание ориентации. Подпись потока пикселей тоже не изменилась. Последняя панель переставлена физически; метка 1 сама по себе не доказывает правильное положение предмета.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$tagOnly = clone $source;
$tagOnly->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
$upright = clone $source; $upright->autoOrient();
saveOrientationPNG($tagOnly, 'tag-only.png', true); saveOrientationPNG($upright, 'control-upright.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($tagOnly), orientationPreview($upright)], 'orientation-controls.png');
echo "orientation-controls.png\ntag-only.png\ncontrol-upright.png\n";
printf("tag=%d same-pixels=%d same-signature=%d upright=%d\n", $tagOnly->getImageOrientation(), (int)(orientationPixelHash($source) === orientationPixelHash($tagOnly)), (int)($source->getImageSignature() === $tagOnly->getImageSignature()), $upright->getImageOrientation());
Средняя панель остаётся боком: setter поменял только указание ориентации. Подпись потока пикселей тоже не изменилась. Последняя панель переставлена физически; метка 1 сама по себе не доказывает правильное положение предмета. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-controls.png
tag-only.png
control-upright.png
tag=1 same-pixels=1 same-signature=1 upright=1
Прочитать указание и проверить доставку после повторного чтения
Самая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$orientation = $image->getImageOrientation();
echo $orientation;Пустые скобки означают отсутствие аргументов. Для нашего входа прочитано RIGHTTOP, в этой сборке код 6. Getter читает указание, не распознаёт верх фотографии по содержимому и не поворачивает пиксели. ORIENTATION_UNDEFINED сообщает, что надёжного указания нет; код 0 не является bool false.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.

Прочитать указание ориентации и решить, нужна ли нормализация
Getter возвращает целый код, здесь RIGHTTOP. Условие выбирает обработку, а сам getter ничего не поворачивает. UNDEFINED не сообщает, как предмет должен стоять: в минимальном примере мы не угадываем отсутствующую информацию.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$orientation = $source->getImageOrientation();
$needsNormalization = $orientation !== Imagick::ORIENTATION_TOPLEFT && $orientation !== Imagick::ORIENTATION_UNDEFINED;
$result = clone $source;
if ($needsNormalization) { $result->autoOrient(); }
saveOrientationPNG($result, 'getter-upright.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($result)], 'orientation-get.png');
echo "orientation-get.png\ngetter-upright.png\n";
printf("orientation=%d needs-normalization=%d result=%d\n", $orientation, (int)$needsNormalization, $result->getImageOrientation());
Getter возвращает целый код, здесь RIGHTTOP. Условие выбирает обработку, а сам getter ничего не поворачивает. UNDEFINED не сообщает, как предмет должен стоять: в минимальном примере мы не угадываем отсутствующую информацию. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-get.png
getter-upright.png
orientation=6 needs-normalization=1 result=1
Для второй задачи важно обработать уже готовый файл повторно и не повернуть его ещё раз по старому предположению. in_array(..., true) проверяет принадлежность разрешённому списку с учётом типа. Это выбранная проверка входа, не обещание автоматического отказа Imagick. У UNDEFINED нет достоверного направления: в таком проекте нужна отдельная договорённость с поставщиком или ручное решение.
Проверить направление после записи и безопасно обработать повторно
Для доставки наша политика требует известный код из восьми вариантов. После записи проверяем метку заново. Повторный autoOrient на нормализованном результате не меняет его пиксели в этой проверке; это помогает избежать повторного ручного поворота по старой метке.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$allowed = [Imagick::ORIENTATION_TOPLEFT, Imagick::ORIENTATION_TOPRIGHT, Imagick::ORIENTATION_BOTTOMRIGHT, Imagick::ORIENTATION_BOTTOMLEFT, Imagick::ORIENTATION_LEFTTOP, Imagick::ORIENTATION_RIGHTTOP, Imagick::ORIENTATION_RIGHTBOTTOM, Imagick::ORIENTATION_LEFTBOTTOM];
if (!in_array($source->getImageOrientation(), $allowed, true)) { throw new RuntimeException('Orientation needs a known policy'); }
$normalized = clone $source; $normalized->autoOrient();
saveOrientationPNG($normalized, 'delivery.png', true);
$delivery = new Imagick(__DIR__ . '/delivery.png');
if ($delivery->getImageOrientation() !== Imagick::ORIENTATION_TOPLEFT) { throw new RuntimeException('Delivery orientation is not normalized'); }
$second = clone $delivery; $second->autoOrient();
saveOrientationPNG($second, 'delivery-second.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($delivery), orientationPreview($second)], 'orientation-delivery-check.png');
echo "orientation-delivery-check.png\ndelivery.png\ndelivery-second.png\n";
printf("delivery=%d second-same=%d size=%dx%d\n", $delivery->getImageOrientation(), (int)(orientationPixelHash($delivery) === orientationPixelHash($second)), $delivery->getImageWidth(), $delivery->getImageHeight());
Для доставки наша политика требует известный код из восьми вариантов. После записи проверяем метку заново. Повторный autoOrient на нормализованном результате не меняет его пиксели в этой проверке; это помогает избежать повторного ручного поворота по старой метке. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-delivery-check.png
delivery.png
delivery-second.png
delivery=1 second-same=1 size=320x400
Назначать метку по известному происхождению и учитывать отражения
Самая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$ok = $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);TOPLEFT говорит: пиксели уже стоят обычно. Делайте такое назначение, когда их происхождение известно, например сразу после физической нормализации. Метод возвращает true при успехе; результат изображения остаётся в $image. Если исходный растр лежит боком, одна эта строка не исправит его. Неверная метка может заставить другую программу показать его иначе.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.
Исправить известную неверную метку уже правильно стоящих пикселей
Здесь положение пикселей известно: его только что получили физической нормализацией. Намеренно неверную метку 6 заменяем на 1 без второго поворота. Две последние нейтральные панели одинаковы по пикселям; потенциальное поведение стороннего просмотрщика не моделируется.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$alreadyUpright = clone $source; $alreadyUpright->autoOrient();
$wrongTag = clone $alreadyUpright;
$wrongTag->setImageOrientation(Imagick::ORIENTATION_RIGHTTOP);
$fixedTag = clone $wrongTag;
if (!$fixedTag->setImageOrientation(Imagick::ORIENTATION_TOPLEFT)) { throw new RuntimeException('Tag change failed'); }
saveOrientationPNG($fixedTag, 'fixed-tag.png', true);
$read = new Imagick(__DIR__ . '/fixed-tag.png');
saveOrientationComparison([$sourceWhite, orientationPreview($wrongTag), orientationPreview($read)], 'orientation-tag-repair.png');
echo "orientation-tag-repair.png\nfixed-tag.png\n";
printf("wrong=%d fixed=%d same-pixels=%d\n", $wrongTag->getImageOrientation(), $read->getImageOrientation(), (int)(orientationPixelHash($wrongTag) === orientationPixelHash($read)));
Здесь положение пикселей известно: его только что получили физической нормализацией. Намеренно неверную метку 6 заменяем на 1 без второго поворота. Две последние нейтральные панели одинаковы по пикселям; потенциальное поведение стороннего просмотрщика не моделируется. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-tag-repair.png
fixed-tag.png
wrong=6 fixed=1 same-pixels=1
Вторая задача — известный зеркальный источник. flopImage отражает растр слева направо; здесь это открытая подготовка контролируемого примера, а не автоматическое определение зеркальности. После такого отражения нашего входа корректирующее указание RIGHTBOTTOM означает поперечное отражение с перестановкой осей. Произвольной фотографии такой код по догадке назначать нельзя. Восемь действий из модели не сводятся к четырём поворотам: буквы в углах помогают заметить ошибочное отражение.

Описать известный зеркальный вход и получить обычную доставку
Собственное отражение исходника имеет известное происхождение. Для него назначаем RIGHTBOTTOM и затем нормализуем: сочетание отражения и перестановки осей возвращает читаемую карточку. Восемь orientation-вариантов включают четыре зеркальных; простой rotate на 90 градусов их все не заменяет.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$mirrored = clone $source;
$mirrored->flopImage();
$mirrored->setImageOrientation(Imagick::ORIENTATION_RIGHTBOTTOM);
saveOrientationPNG($mirrored, 'mirrored-tagged.png', true);
$normalized = clone $mirrored; $normalized->autoOrient();
$normalized->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
saveOrientationPNG($normalized, 'mirror-upright.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($mirrored), orientationPreview($normalized)], 'orientation-mirror.png');
echo "orientation-mirror.png\nmirrored-tagged.png\nmirror-upright.png\n";
printf("assigned=%d normalized=%d size=%dx%d\n", $mirrored->getImageOrientation(), $normalized->getImageOrientation(), $normalized->getImageWidth(), $normalized->getImageHeight());
Собственное отражение исходника имеет известное происхождение. Для него назначаем RIGHTBOTTOM и затем нормализуем: сочетание отражения и перестановки осей возвращает читаемую карточку. Восемь orientation-вариантов включают четыре зеркальных; простой rotate на 90 градусов их все не заменяет. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-mirror.png
mirrored-tagged.png
mirror-upright.png
assigned=7 normalized=1 size=320x400
Отличать точные данные, разные файлы и похожие изображения
Самая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$signature = $image->getImageSignature();
echo $signature;Подпись — короткая контрольная строка по данным, прочитанным библиотекой; SHA-256 — применённый алгоритм хеширования. Метод заново вычисляет её для текущего изображения. Для SHA байтов файла используется отдельная hash_file('sha256', $path). Подпись не определяет, правильно ли стоит предмет, и не оценивает похожесть фотографий. Сравнивайте в одной среде вместе с размерами, цветовой моделью, каналами и одинаковым правилом обработки.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.

Отделить подпись пикселей от SHA двух сохранённых файлов
Оба файла записаны одним способом из одинаковых пикселей; у копии другой комментарий. Их SHA файлов различаются, подписи потоков пикселей и декодированные RGBA совпадают. Это проверка в одной сборке, а не универсальный идентификатор между любыми форматами и декодерами.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$copy = clone $source;
$copy->setImageProperty('comment', 'Another description; the same pixel stream');
$signatureA = $source->getImageSignature(); $signatureB = $copy->getImageSignature();
saveOrientationPNG($source, 'signature-a.png', true); saveOrientationPNG($copy, 'signature-b.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($copy)], 'orientation-signature-metadata.png');
echo "orientation-signature-metadata.png\nsignature-a.png\nsignature-b.png\n";
printf("signature-length=%d same-pixels=%d same-signature=%d same-file=%d\n", strlen($signatureA), (int)(orientationPixelHash($source) === orientationPixelHash($copy)), (int)($signatureA === $signatureB), (int)(hash_file('sha256', __DIR__ . '/signature-a.png') === hash_file('sha256', __DIR__ . '/signature-b.png')));
Оба файла записаны одним способом из одинаковых пикселей; у копии другой комментарий. Их SHA файлов различаются, подписи потоков пикселей и декодированные RGBA совпадают. Это проверка в одной сборке, а не универсальный идентификатор между любыми форматами и декодерами. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-signature-metadata.png
signature-a.png
signature-b.png
signature-length=64 same-pixels=1 same-signature=1 same-file=0
Во второй задаче сравниваем доставку после приведения к одному направлению. getImageColorspace читает цветовую модель, getImageAlphaChannel — состояние канала, они дополняют размеры и подпись. Это ещё не полноценный поиск похожих фотографий. ImagickDraw ниже создаёт перо: setStrokeColor выбирает красный цвет линии, setStrokeWidth задаёт ширину 4 пикселя, line — её концы (40,247) и (280,247), drawImage наносит линию на копию. Такой видимый контроль меняет поток пикселей; повторная запись комментария его не меняет.
Проверить точную нормализованную копию и обнаружить видимую правку
Перед сравнением изображения приведены к одному направлению. Проверяем размеры, цветовую модель, состояние alpha и подпись в той же среде. Точная сохранённая копия проходит; добавленная красная линия меняет подпись. Сходные фотографии, антиалиасинг и поиск похожих изображений требуют другой задачи и критериев.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$normal = clone $source; $normal->autoOrient();
saveOrientationPNG($normal, 'signature-normal.png', true);
$copy = clone $normal; $copy->setImageProperty('comment', 'Same normalized delivery');
saveOrientationPNG($copy, 'signature-copy.png', true);
$read = new Imagick(__DIR__ . '/signature-copy.png');
$edited = clone $normal;
$pen = new ImagickDraw(); $pen->setStrokeColor('#c7413c'); $pen->setStrokeWidth(4); $pen->line(40, 247, 280, 247);
$edited->drawImage($pen); saveOrientationPNG($edited, 'signature-edited.png', true);
$sameGeometry = $normal->getImageWidth() === $read->getImageWidth() && $normal->getImageHeight() === $read->getImageHeight();
$sameContext = $normal->getImageColorspace() === $read->getImageColorspace() && $normal->getImageAlphaChannel() === $read->getImageAlphaChannel();
$exactCopy = $sameGeometry && $sameContext && $normal->getImageSignature() === $read->getImageSignature();
saveOrientationComparison([orientationPreview($normal), orientationPreview($read), orientationPreview($edited)], 'orientation-signature-delivery.png');
echo "orientation-signature-delivery.png\nsignature-normal.png\nsignature-copy.png\nsignature-edited.png\n";
printf("normalized-copy=%d edited-copy=%d geometry=%dx%d\n", (int)$exactCopy, (int)($normal->getImageSignature() === $edited->getImageSignature()), $normal->getImageWidth(), $normal->getImageHeight());
Перед сравнением изображения приведены к одному направлению. Проверяем размеры, цветовую модель, состояние alpha и подпись в той же среде. Точная сохранённая копия проходит; добавленная красная линия меняет подпись. Сходные фотографии, антиалиасинг и поиск похожих изображений требуют другой задачи и критериев. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-signature-delivery.png
signature-normal.png
signature-copy.png
signature-edited.png
normalized-copy=1 edited-copy=0 geometry=320x400
Проверять ошибки, alpha, запись и границы подписи
| Ситуация | Проверка и граница |
|---|---|
| Поставили TOPLEFT, а текст боком | Setter меняет указание. Сначала нужно знать, как стоят пиксели; физическое исправление выполняется отдельно. |
| Все повороты учли, отражение осталось | Ориентации 2/4/5/7 включают зеркальность. Проверьте буквы/детали асимметричного изображения. |
| Getter вернул 0 | Это UNDEFINED, целый код отсутствующего указания, не ошибка bool. Метод не определяет верх по сюжету. |
| Повторная обработка повернула дважды | Не применяйте старый ручной угол к уже нормализованным пикселям. Проверяйте сохранённый файл и метку TOPLEFT. |
| Файлы имеют разные SHA | Служебные записи, формат и кодирование тоже являются байтами файла. Для текущих пикселей есть отдельная подпись. |
| Подписи совпали | В нашей среде сравнение дополняется размерами, цветовой моделью и alpha. Подпись не включает геометрию отдельными полями и зависит от того, какие компоненты читаются. |
| Почти одинаковые картинки имеют разные подписи | Даже небольшая правка или другое сглаживание могут менять данные. Для похожести нужен отдельный критерий, здесь он не реализован. |
| Один файл дал разные подписи на разных компьютерах | Сравните версии, декодер, цветовое представление и точность. Переносимую идентичность между любыми сборками не обещаем. |
| Прозрачность после поворота | В наших сохранённых RGBA-проверках компоненты и alpha точно переставлены. Цвет подложки просмотра не доказывает alpha; самостоятельный PNG проверен отдельно. |
| Загрузка со смартфона | Сервер обрабатывает файл после его получения. Проверка upload, лимиты и публикация — отдельный этап; чужой небезопасный обработчик из обсуждения не переносится. |
| JPEG/EXIF/сторонний просмотрщик | Эта глава фактически проверяет собственные PNG и одну сборку. Поведение всех камер, приложений, JPEG-кодирования и метаданных не обобщаем. |
Обрабатывается текущее изображение, не автоматически все кадры анимации. Повороты на прямой угол здесь переставляют сетку, и размеры 400 × 320 становятся 320 × 400; принудительного растягивания или обрезки нет. Подпись заново проходит по данным, поэтому её вычисление имеет стоимость чтения изображения; абсолютных обещаний скорости не делаем.
Полный helper из каждого архива примера
<?php
declare(strict_types=1);
function restoreOrientationInput(): void {
$text = file_get_contents(__DIR__ . '/source.png.b64');
if ($text === false) { throw new RuntimeException('Input missing'); }
$bytes = base64_decode($text, true);
if ($bytes === false || hash('sha256', $bytes) !== 'c89a6a08a2f4354797ae7160357e96c72480c7ff8558da16d548a471350eaafa') { throw new RuntimeException('Input mismatch'); }
if (file_put_contents(__DIR__ . '/source.png', $bytes) === false) { throw new RuntimeException('Restore failed'); }
}
function orientationPreview(Imagick $image, string $background = 'white'): Imagick {
$view = new Imagick(); $view->newImage($image->getImageWidth(), $image->getImageHeight(), $background);
$view->compositeImage($image, Imagick::COMPOSITE_OVER, 0, 0); return $view;
}
function saveOrientationPNG(Imagick $image, string $filename, bool $alpha = false): void {
$copy = clone $image; $copy->setImageFormat('png'); $copy->setImageDepth(8);
$copy->setOption('png:bit-depth', '8'); $copy->setOption('png:color-type', $alpha ? '6' : '2');
if (!$copy->writeImage(__DIR__ . '/' . $filename)) { throw new RuntimeException('PNG write failed'); }
}
function saveOrientationComparison(array $panels, string $filename): void {
$width = 0; $height = 0;
foreach ($panels as $panel) { $width += $panel->getImageWidth(); $height = max($height, $panel->getImageHeight()); }
$canvas = new Imagick(); $canvas->newImage($width, $height, 'white'); $x = 0;
foreach ($panels as $panel) { $canvas->compositeImage($panel, Imagick::COMPOSITE_OVER, $x, intdiv($height - $panel->getImageHeight(), 2)); $x += $panel->getImageWidth(); }
saveOrientationPNG($canvas, $filename);
}
function orientationPixelHash(Imagick $image): string {
return hash('sha256', json_encode($image->exportImagePixels(0, 0, $image->getImageWidth(), $image->getImageHeight(), 'RGBA', Imagick::PIXEL_DOUBLE), JSON_THROW_ON_ERROR));
}
| Прочитанная реальная проблема | Применение и предел |
|---|---|
| SO 4266656 | Автор приложения печати видит одну ориентацию в просмотрщике и другую при обработке; предполагает автоматический поворот при чтении. Показываем реальные хранимые пиксели отдельно от orientation, без принятия предположения вопроса за факт. |
| SO 19456036 | Камера сохраняет пиксели в альбомном положении и метку для показа. Требуется файл, который выглядит правильно и без интерпретации метаданных. |
| SO 54074544 | Обычная браузерная загрузка устраивает автора, а фотография с камеры смартфона приходит повёрнутой. Нужен отдельный понятный этап обработки после получения сервером временного файла и до публикации результата. Небезопасные детали исходного обработчика не переносим. |
| SO 25119285 | Пользователь сравнивает getImageSignature на разных ОС и версиях ImageMagick и ожидает универсальный идентификатор. Фиксируем точную сборку и представление данных, не обещаем переносимость между декодерами, HDRI и версиями. |
| SO 45063226 | В систему приходят изображения с одинаковым содержимым и разными метаданными; удаление метаданных с повторным кодированием не делает файловые хеши одинаковыми. Само повторное кодирование тоже меняет файл. |
| SO 33713773 | Поиск повторных загрузок сталкивается с небольшими различиями сглаживания: картинки кажутся одинаковыми, а файловые и Imagick-подписи отличаются. Это другая постановка задачи, чем точное равенство пикселей. |
TOPLEFT относится к ориентации, а не к виртуальной странице — дополнительным размерам и смещению холста. После некоторых отражений они могут отличаться от ширины и высоты пикселей. Для выбранного входа RIGHTTOP самостоятельный результат проверен с нулевым смещением. Если другому проекту нужен самостоятельный холст с началом в (0, 0), его виртуальную страницу следует проверить и при необходимости явно сбросить через setImagePage; один код TOPLEFT этого не обещает.
Выбрать обработку под достоверную метку и реального получателя

Упражнение: готовая карточка уже прямая, но поставщик оставил RIGHTTOP. Решение при подтверждённом происхождении — назначить TOPLEFT и проверить, что пиксели не изменились. Если исходные пиксели лежат боком и метка достоверна, сначала autoOrient, затем запись и повторное чтение. Для поиска похожих фотографий точная подпись не подходит: отдельный проект должен определить допустимые изменения.
Дальше: самостоятельные вставки и виртуальная страница, прозрачность и выбранный фон, формат и реальные байты файла, цветовые модели и преобразование. Существующие узлы rotate/flip/flop и контекстный autoOrient не меняют владельцев и не засчитываются как новые официальные API.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
Imagick::getImageOrientationВозвращает int — текущий код ориентации. Никакой угол в градусах не передаётся.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::getImageOrientation(): intСамая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$orientation = $image->getImageOrientation();
echo $orientation;Пустые скобки означают отсутствие аргументов. Для нашего входа прочитано RIGHTTOP, в этой сборке код 6. Getter читает указание, не распознаёт верх фотографии по содержимому и не поворачивает пиксели. ORIENTATION_UNDEFINED сообщает, что надёжного указания нет; код 0 не является bool false.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.
Полный официальный контракт
Imagick::getImageOrientation(): int| Параметр | Смысл |
|---|---|
| Нет аргументов | Возвращает int — текущий код ориентации. Никакой угол в градусах не передаётся. |
Gets the image orientation. The return value is one of the orientation constants . Доступность: PECL imagick 2, PECL imagick 3.
Все три метода работают с текущим изображением объекта; для пустого Imagick PHP-обёртка 3.8.1 бросает ImagickException. Для setter официальный XML не содержит отдельной секции ошибок: уточнение реализации добавлено здесь, исходный контракт сохранён целиком. Список разрешённых ориентаций во внешнем вводе — наша политика, автоматическую проверку любого int библиотекой не обещаем.
| Константа Imagick::ORIENTATION_* | Код этой сборки | Корректирующее действие autoOrient |
|---|---|---|
| TOPLEFT | 1 | Обычное положение; копия без перестановки. |
| TOPRIGHT | 2 | Отразить слева направо. |
| BOTTOMRIGHT | 3 | Повернуть на 180°. |
| BOTTOMLEFT | 4 | Отразить сверху вниз. |
| LEFTTOP | 5 | Транспонировать: поменять оси с отражением. |
| RIGHTTOP | 6 | Повернуть на 90° по часовой стрелке. |
| RIGHTBOTTOM | 7 | Поперечное отражение с перестановкой осей. |
| LEFTBOTTOM | 8 | Повернуть на 270° по часовой стрелке. |
UNDEFINED — отсутствие определённого указания. Для него текущая реализация autoOrient копирует растр и выставляет TOPLEFT; это не доказательство, что верх найден. Используйте имена констант вместо предположений о числах.
Полный исходный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimageorientation">
<refnamediv>
<refname>Imagick::getImageOrientation</refname>
<refpurpose>Gets the image orientation</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>int</type><methodname>Imagick::getImageOrientation</methodname>
<void/>
</methodsynopsis>
<para>
Gets the image orientation. The return value is one of the <link
linkend="imagick.constants.orientation">orientation constants</link>.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns an int on success.
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
&imagick.imagick.throws;
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Прочитать указание ориентации и решить, нужна ли нормализация
Getter возвращает целый код, здесь RIGHTTOP. Условие выбирает обработку, а сам getter ничего не поворачивает. UNDEFINED не сообщает, как предмет должен стоять: в минимальном примере мы не угадываем отсутствующую информацию.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$orientation = $source->getImageOrientation();
$needsNormalization = $orientation !== Imagick::ORIENTATION_TOPLEFT && $orientation !== Imagick::ORIENTATION_UNDEFINED;
$result = clone $source;
if ($needsNormalization) { $result->autoOrient(); }
saveOrientationPNG($result, 'getter-upright.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($result)], 'orientation-get.png');
echo "orientation-get.png\ngetter-upright.png\n";
printf("orientation=%d needs-normalization=%d result=%d\n", $orientation, (int)$needsNormalization, $result->getImageOrientation());
Getter возвращает целый код, здесь RIGHTTOP. Условие выбирает обработку, а сам getter ничего не поворачивает. UNDEFINED не сообщает, как предмет должен стоять: в минимальном примере мы не угадываем отсутствующую информацию. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-get.png
getter-upright.png
orientation=6 needs-normalization=1 result=1
Проверить направление после записи и безопасно обработать повторно
Для доставки наша политика требует известный код из восьми вариантов. После записи проверяем метку заново. Повторный autoOrient на нормализованном результате не меняет его пиксели в этой проверке; это помогает избежать повторного ручного поворота по старой метке.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$allowed = [Imagick::ORIENTATION_TOPLEFT, Imagick::ORIENTATION_TOPRIGHT, Imagick::ORIENTATION_BOTTOMRIGHT, Imagick::ORIENTATION_BOTTOMLEFT, Imagick::ORIENTATION_LEFTTOP, Imagick::ORIENTATION_RIGHTTOP, Imagick::ORIENTATION_RIGHTBOTTOM, Imagick::ORIENTATION_LEFTBOTTOM];
if (!in_array($source->getImageOrientation(), $allowed, true)) { throw new RuntimeException('Orientation needs a known policy'); }
$normalized = clone $source; $normalized->autoOrient();
saveOrientationPNG($normalized, 'delivery.png', true);
$delivery = new Imagick(__DIR__ . '/delivery.png');
if ($delivery->getImageOrientation() !== Imagick::ORIENTATION_TOPLEFT) { throw new RuntimeException('Delivery orientation is not normalized'); }
$second = clone $delivery; $second->autoOrient();
saveOrientationPNG($second, 'delivery-second.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($delivery), orientationPreview($second)], 'orientation-delivery-check.png');
echo "orientation-delivery-check.png\ndelivery.png\ndelivery-second.png\n";
printf("delivery=%d second-same=%d size=%dx%d\n", $delivery->getImageOrientation(), (int)(orientationPixelHash($delivery) === orientationPixelHash($second)), $delivery->getImageWidth(), $delivery->getImageHeight());
Для доставки наша политика требует известный код из восьми вариантов. После записи проверяем метку заново. Повторный autoOrient на нормализованном результате не меняет его пиксели в этой проверке; это помогает избежать повторного ручного поворота по старой метке. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-delivery-check.png
delivery.png
delivery-second.png
delivery=1 second-same=1 size=320x400
Imagick::setImageOrientationОбязательный int, именованная константа ORIENTATION_*. Это код выбора, не угол/процент. Возвращает bool-статус, меняет метку текущего изображения.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::setImageOrientation(int $orientation): boolСамая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$ok = $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);TOPLEFT говорит: пиксели уже стоят обычно. Делайте такое назначение, когда их происхождение известно, например сразу после физической нормализации. Метод возвращает true при успехе; результат изображения остаётся в $image. Если исходный растр лежит боком, одна эта строка не исправит его. Неверная метка может заставить другую программу показать его иначе.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.
Полный официальный контракт
Imagick::setImageOrientation(int $orientation): bool| Параметр | Смысл |
|---|---|
| $orientation | Обязательный int, именованная константа ORIENTATION_*. Это код выбора, не угол/процент. Возвращает bool-статус, меняет метку текущего изображения. |
Sets the image orientation. Доступность: PECL imagick 2, PECL imagick 3.
Все три метода работают с текущим изображением объекта; для пустого Imagick PHP-обёртка 3.8.1 бросает ImagickException. Для setter официальный XML не содержит отдельной секции ошибок: уточнение реализации добавлено здесь, исходный контракт сохранён целиком. Список разрешённых ориентаций во внешнем вводе — наша политика, автоматическую проверку любого int библиотекой не обещаем.
| Константа Imagick::ORIENTATION_* | Код этой сборки | Корректирующее действие autoOrient |
|---|---|---|
| TOPLEFT | 1 | Обычное положение; копия без перестановки. |
| TOPRIGHT | 2 | Отразить слева направо. |
| BOTTOMRIGHT | 3 | Повернуть на 180°. |
| BOTTOMLEFT | 4 | Отразить сверху вниз. |
| LEFTTOP | 5 | Транспонировать: поменять оси с отражением. |
| RIGHTTOP | 6 | Повернуть на 90° по часовой стрелке. |
| RIGHTBOTTOM | 7 | Поперечное отражение с перестановкой осей. |
| LEFTBOTTOM | 8 | Повернуть на 270° по часовой стрелке. |
UNDEFINED — отсутствие определённого указания. Для него текущая реализация autoOrient копирует растр и выставляет TOPLEFT; это не доказательство, что верх найден. Используйте имена констант вместо предположений о числах.
Полный исходный официальный пример 1
Это HTTP-контекст официального руководства. Функция получает путь и ориентацию, но setter лишь назначает метку. Заголовок Content-Type не перекодирует getImageBlob в JPEG. Пример сохранён полностью; самостоятельные CLI-программы ниже показывают фактические PNG и физический поворот.
<?php
//Doesn't appear to do anything
function setImageOrientation($imagePath, $orientationType) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->setImageOrientation($orientationType);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
}
?>
Полный исходный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimageorientation">
<refnamediv>
<refname>Imagick::setImageOrientation</refname>
<refpurpose>Sets the image orientation</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageOrientation</methodname>
<methodparam><type>int</type><parameter>orientation</parameter></methodparam>
</methodsynopsis>
<para>
Sets the image orientation.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>orientation</parameter></term>
<listitem>
<para>
One of the <link linkend="imagick.constants.orientation">orientation constants</link>
</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::setImageOrientation</function></title>
<programlisting role="php">
<![CDATA[
<?php
//Doesn't appear to do anything
function setImageOrientation($imagePath, $orientationType) {
$imagick = new \Imagick(realpath($imagePath));
$imagick->setImageOrientation($orientationType);
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
-->
Исправить известную неверную метку уже правильно стоящих пикселей
Здесь положение пикселей известно: его только что получили физической нормализацией. Намеренно неверную метку 6 заменяем на 1 без второго поворота. Две последние нейтральные панели одинаковы по пикселям; потенциальное поведение стороннего просмотрщика не моделируется.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$alreadyUpright = clone $source; $alreadyUpright->autoOrient();
$wrongTag = clone $alreadyUpright;
$wrongTag->setImageOrientation(Imagick::ORIENTATION_RIGHTTOP);
$fixedTag = clone $wrongTag;
if (!$fixedTag->setImageOrientation(Imagick::ORIENTATION_TOPLEFT)) { throw new RuntimeException('Tag change failed'); }
saveOrientationPNG($fixedTag, 'fixed-tag.png', true);
$read = new Imagick(__DIR__ . '/fixed-tag.png');
saveOrientationComparison([$sourceWhite, orientationPreview($wrongTag), orientationPreview($read)], 'orientation-tag-repair.png');
echo "orientation-tag-repair.png\nfixed-tag.png\n";
printf("wrong=%d fixed=%d same-pixels=%d\n", $wrongTag->getImageOrientation(), $read->getImageOrientation(), (int)(orientationPixelHash($wrongTag) === orientationPixelHash($read)));
Здесь положение пикселей известно: его только что получили физической нормализацией. Намеренно неверную метку 6 заменяем на 1 без второго поворота. Две последние нейтральные панели одинаковы по пикселям; потенциальное поведение стороннего просмотрщика не моделируется. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-tag-repair.png
fixed-tag.png
wrong=6 fixed=1 same-pixels=1
Описать известный зеркальный вход и получить обычную доставку
Собственное отражение исходника имеет известное происхождение. Для него назначаем RIGHTBOTTOM и затем нормализуем: сочетание отражения и перестановки осей возвращает читаемую карточку. Восемь orientation-вариантов включают четыре зеркальных; простой rotate на 90 градусов их все не заменяет.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$mirrored = clone $source;
$mirrored->flopImage();
$mirrored->setImageOrientation(Imagick::ORIENTATION_RIGHTBOTTOM);
saveOrientationPNG($mirrored, 'mirrored-tagged.png', true);
$normalized = clone $mirrored; $normalized->autoOrient();
$normalized->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
saveOrientationPNG($normalized, 'mirror-upright.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($mirrored), orientationPreview($normalized)], 'orientation-mirror.png');
echo "orientation-mirror.png\nmirrored-tagged.png\nmirror-upright.png\n";
printf("assigned=%d normalized=%d size=%dx%d\n", $mirrored->getImageOrientation(), $normalized->getImageOrientation(), $normalized->getImageWidth(), $normalized->getImageHeight());
Собственное отражение исходника имеет известное происхождение. Для него назначаем RIGHTBOTTOM и затем нормализуем: сочетание отражения и перестановки осей возвращает читаемую карточку. Восемь orientation-вариантов включают четыре зеркальных; простой rotate на 90 градусов их все не заменяет. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-mirror.png
mirrored-tagged.png
mirror-upright.png
assigned=7 normalized=1 size=320x400
Imagick::getImageSignatureВозвращает string с SHA-256 подписью текущего потока компонент, в проверке 64 шестнадцатеричных символа. Не принимает путь файла.
PECL imagick 2, PECL imagick 3 · imagick
Imagick::getImageSignature(): stringСамая маленькая запись
Растр — сетка хранимых пикселей. RGB задаёт красную, зелёную и синюю компоненты; RGBA добавляет alpha: 0 — прозрачный, 1 — непрозрачный. Ориентация — отдельное указание, как расположить растр при показе. $image — переменная с объектом изображения; $ начинает имя, = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. Imagick:: обращается к именованной константе класса. Число ORIENTATION_* не является углом. clone создаёт независимую рабочую копию.
$signature = $image->getImageSignature();
echo $signature;Подпись — короткая контрольная строка по данным, прочитанным библиотекой; SHA-256 — применённый алгоритм хеширования. Метод заново вычисляет её для текущего изображения. Для SHA байтов файла используется отдельная hash_file('sha256', $path). Подпись не определяет, правильно ли стоит предмет, и не оценивает похожесть фотографий. Сравнивайте в одной среде вместе с размерами, цветовой моделью, каналами и одинаковым правилом обработки.
В полных примерах if выбирает действие по условию, ! отрицает его, === сравнивает значение и тип, !== означает строгое неравенство; && требует выполнения обоих условий. (int) показывает bool как 1/0. echo выводит текст; printf подставляет %d как целое число, "\n" означает новую строку. __DIR__ — папка программы, . соединяет строки пути. if с throw new RuntimeException прекращает обработку при нарушении нашей проверки. Подробнее: объекты и методы, файлы, ошибки и исключения.
Полный официальный контракт
Imagick::getImageSignature(): string| Параметр | Смысл |
|---|---|
| Нет аргументов | Возвращает string с SHA-256 подписью текущего потока компонент, в проверке 64 шестнадцатеричных символа. Не принимает путь файла. |
Generates an SHA-256 message digest for the image pixel stream. Доступность: PECL imagick 2, PECL imagick 3.
Все три метода работают с текущим изображением объекта; для пустого Imagick PHP-обёртка 3.8.1 бросает ImagickException. Для setter официальный XML не содержит отдельной секции ошибок: уточнение реализации добавлено здесь, исходный контракт сохранён целиком. Список разрешённых ориентаций во внешнем вводе — наша политика, автоматическую проверку любого int библиотекой не обещаем.
В официальном XML описание говорит pixel stream, а абзац результата — hash of the file. По точному коду это подпись текущих компонент, не исходных байтов файла. Читаются разрешённые к обновлению каналы и учитывается маска чтения; размеры не добавляются отдельными полями. В этой главе нет масок, сравниваются одинаково загруженные RGB/RGBA в одной сборке. Подпись не заменяет отдельные проверки геометрии и alpha и не обещает переносимость между версиями, декодерами и точностью сборки.
Полный исходный XML без сокращений
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagesignature">
<refnamediv>
<refname>Imagick::getImageSignature</refname>
<refpurpose>Generates an SHA-256 message digest</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<modifier>public</modifier> <type>string</type><methodname>Imagick::getImageSignature</methodname>
<void/>
</methodsynopsis>
<para>
Generates an SHA-256 message digest for the image pixel stream.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
&no.function.parameters;
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Returns a string containing the SHA-256 hash of the file.
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
&imagick.imagick.throws;
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
Отделить подпись пикселей от SHA двух сохранённых файлов
Оба файла записаны одним способом из одинаковых пикселей; у копии другой комментарий. Их SHA файлов различаются, подписи потоков пикселей и декодированные RGBA совпадают. Это проверка в одной сборке, а не универсальный идентификатор между любыми форматами и декодерами.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$copy = clone $source;
$copy->setImageProperty('comment', 'Another description; the same pixel stream');
$signatureA = $source->getImageSignature(); $signatureB = $copy->getImageSignature();
saveOrientationPNG($source, 'signature-a.png', true); saveOrientationPNG($copy, 'signature-b.png', true);
saveOrientationComparison([$sourceWhite, orientationPreview($copy)], 'orientation-signature-metadata.png');
echo "orientation-signature-metadata.png\nsignature-a.png\nsignature-b.png\n";
printf("signature-length=%d same-pixels=%d same-signature=%d same-file=%d\n", strlen($signatureA), (int)(orientationPixelHash($source) === orientationPixelHash($copy)), (int)($signatureA === $signatureB), (int)(hash_file('sha256', __DIR__ . '/signature-a.png') === hash_file('sha256', __DIR__ . '/signature-b.png')));
Оба файла записаны одним способом из одинаковых пикселей; у копии другой комментарий. Их SHA файлов различаются, подписи потоков пикселей и декодированные RGBA совпадают. Это проверка в одной сборке, а не универсальный идентификатор между любыми форматами и декодерами. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-signature-metadata.png
signature-a.png
signature-b.png
signature-length=64 same-pixels=1 same-signature=1 same-file=0
Проверить точную нормализованную копию и обнаружить видимую правку
Перед сравнением изображения приведены к одному направлению. Проверяем размеры, цветовую модель, состояние alpha и подпись в той же среде. Точная сохранённая копия проходит; добавленная красная линия меняет подпись. Сходные фотографии, антиалиасинг и поиск похожих изображений требуют другой задачи и критериев.
<?php
declare(strict_types=1);
require __DIR__ . '/orientation-fixture.php';
restoreOrientationInput();
$source = new Imagick(__DIR__ . '/source.png');
$sourceWhite = orientationPreview($source);
$normal = clone $source; $normal->autoOrient();
saveOrientationPNG($normal, 'signature-normal.png', true);
$copy = clone $normal; $copy->setImageProperty('comment', 'Same normalized delivery');
saveOrientationPNG($copy, 'signature-copy.png', true);
$read = new Imagick(__DIR__ . '/signature-copy.png');
$edited = clone $normal;
$pen = new ImagickDraw(); $pen->setStrokeColor('#c7413c'); $pen->setStrokeWidth(4); $pen->line(40, 247, 280, 247);
$edited->drawImage($pen); saveOrientationPNG($edited, 'signature-edited.png', true);
$sameGeometry = $normal->getImageWidth() === $read->getImageWidth() && $normal->getImageHeight() === $read->getImageHeight();
$sameContext = $normal->getImageColorspace() === $read->getImageColorspace() && $normal->getImageAlphaChannel() === $read->getImageAlphaChannel();
$exactCopy = $sameGeometry && $sameContext && $normal->getImageSignature() === $read->getImageSignature();
saveOrientationComparison([orientationPreview($normal), orientationPreview($read), orientationPreview($edited)], 'orientation-signature-delivery.png');
echo "orientation-signature-delivery.png\nsignature-normal.png\nsignature-copy.png\nsignature-edited.png\n";
printf("normalized-copy=%d edited-copy=%d geometry=%dx%d\n", (int)$exactCopy, (int)($normal->getImageSignature() === $edited->getImageSignature()), $normal->getImageWidth(), $normal->getImageHeight());
Перед сравнением изображения приведены к одному направлению. Проверяем размеры, цветовую модель, состояние alpha и подпись в той же среде. Точная сохранённая копия проходит; добавленная красная линия меняет подпись. Сходные фотографии, антиалиасинг и поиск похожих изображений требуют другой задачи и критериев. Сохраните example.php, source.png.b64 и orientation-fixture.php из архива в одной папке. Запуск: php example.php с расширением Imagick и поддержкой PNG. Исходник восстанавливается из Base64 с проверкой SHA; выходные PNG создаёт сама программа. Helper опубликован полностью ниже, основные методы явно видны в примерах.
Ожидаемый вывод
orientation-signature-delivery.png
signature-normal.png
signature-copy.png
signature-edited.png
normalized-copy=1 edited-copy=0 geometry=320x400
Источники и обсуждения
- Imagick::getImageOrientation
- Imagick::getImageSignature
- Imagick::setImageOrientation
- Imagick 3.8.1 imagick_class.c
- Imagick 3.8.1 imagick_helpers.c
- ImageMagick 7.1.1-46 MagickWand/magick-image.c
- ImageMagick 7.1.1-46 MagickCore/transform.c
- ImageMagick 7.1.1-46 MagickCore/signature.c
- ImageMagick 7.1.1-46 coders/png.c
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


