Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

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

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 321 · От width/height до проверяемого geometry workflow

Imagick: геометрия, размер, crop и virtual canvas

36 официальных методов от первого resize до page geometry: чем отличаются операции, какой результат наблюдать и почему после crop нужен осознанный reset page.

Сначала результат: что должно измениться и как это доказать

Нам нужен не вызов ради вызова, а конкретный продукт: превью 800×600, квадратная карточка без пустых полей, нижние 200 px документа или повёрнутый скан без чёрных углов.

Маршрут одной операции
  1. ограничить вход: coder, width, height, число кадров и decoded cost
  2. сделать маленький несимметричный контрольный пример и назвать ожидаемый эффект
  3. выполнить один новый метод, проверить его return и фактическое состояние объекта
  4. для мутирующей операции записать отдельный PNG-кандидат и проверить размер файла
  5. освободить iterator, draw, reference и image в finally; исходник не перезаписывать

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Не путать операции: одна задача — один осознанный выбор

ЗадачаМетод-отправная точкаЧто проверить
вписать фото в рамкуresizeImage / scaleImageобе стороны не больше лимита, пропорции сохранены
заполнить карточку без полейcropThumbnailImageточный target size и не срезан focal point
оставить прямоугольную областьcropImage + resetImagePagewidth/height и нулевой page offset
удалить одноцветные поляtrimImage + resetImagePageконтент не съеден fuzz-допуском
добавить холстextentImagebackground, offset и итоговый размер
сменить print resolution с пикселямиresampleImageисходное DPI задано и geometry изменилась ожидаемо

Размер: resize, scale, sample, thumbnail и resample

Сначала назовите цель: вписать в рамку, заполнить рамку, изменить DPI с пересчётом или сделать пиксельный nearest-neighbour. Это разные операции.

Отдельные карточки: adaptiveResizeImage, cropThumbnailImage, liquidRescaleImage, magnifyImage, minifyImage, resampleImage, resizeImage, sampleImage, scaleImage, thumbnailImage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Матрицы, distortion, shear и циклический сдвиг

Сложное преобразование проверяют на несимметричной тестовой сетке и измеряют итоговый bounding box.

Отдельные карточки: affineTransformImage, distortImage, rollImage, shearImage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Crop, trim, extent, shave, chop и splice

Crop оставляет область, chop удаляет полосу, shave срезает края, trim ищет одноцветную рамку, extent задаёт холст, splice вставляет пустое место.

Отдельные карточки: chopImage, cropImage, extentImage, setImageExtent, shaveImage, spliceImage, trimImage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Повороты и отражения

Цветные контрольные углы позволяют доказать направление операции; на симметричной картинке это невозможно.

Отдельные карточки: flipImage, flopImage, rotateImage, transposeImage, transverseImage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Измерение фактической геометрии

Getter относится к текущему кадру. Для последовательности сначала выбирают кадр, затем измеряют.

Отдельные карточки: getImageGeometry, getImageHeight, getImageWidth. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Pixel geometry и virtual page

Размер массива пикселей и виртуальный canvas — два разных состояния. Crop/trim могут оставить offset, который влияет на следующую операцию.

Отдельные карточки: getImagePage, getPage, resetImagePage, setImagePage, setPage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Устаревшие геометрические методы

Deprecated-контракт сохраняется для поддержки старого кода, но новый маршрут показывает современную замену.

Отдельные карточки: transformImage. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Преобразование цветового пространства

Метка, профиль и реальное преобразование чисел каналов — разные действия.

Отдельные карточки: transformImageColorspace. Каждая содержит точную сигнатуру, параметры, два входа, отказ, альтернативу и проверку результата.

Граница доказательств и следующий прогон

  • Каждая официальная API-страница этого владельца представлена отдельной карточкой с frozen SHA.
  • У каждой карточки ровно два различающихся самодостаточных примера: синтетический и файловый.
  • Каждый пример проверяет return-контракт и реальный effect; мутирующий workflow пишет отдельный PNG-кандидат.
  • Локальный PHP 8.5.11 не загружает imagick, поэтому заявляется только php -l, а не runtime или visual pass.
  • Кандидат не подключён к shared writers, content, plugin или WordPress.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

Imagick::adaptiveResizeImageУменьшить фотографию, стараясь сохранить резкие границы и мелкие детали.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::adaptiveResizeImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool

Реальная потребность. Уменьшить фотографию, стараясь сохранить резкие границы и мелкие детали.

Что получится. Получить растр в заданной рамке и сравнить его фактические width/height.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::adaptiveResizeImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::adaptiveResizeImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: The number of columns in the scaled image.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: The number of rows in the scaled image.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to fit the image within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Нулевая сторона вместе с bestfit и слишком большой исходник дают ошибку геометрии или дорогую обработку. При ошибке выбрасывается ImagickException.

Граница. Adaptive-алгоритм медленнее обычного resize и не гарантирует лучшую картинку для каждого сюжета.

Что выбрать рядом. Resizeimage для предсказуемого фильтра или thumbnailimage для превью.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: уменьшить фотографию, стараясь сохранить резкие границы и мелкие деталиПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->adaptiveResizeImage(6, 4, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 6 && $afterGeometry['height'] <= 4;
    $artifact = __DIR__ . '/out/' . 'adaptiveresizeimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::adaptiveResizeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: получить растр в заданной рамке и сравнить его фактические width/heightПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->adaptiveResizeImage(8, 5, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 8 && $afterGeometry['height'] <= 5;
    $artifact = __DIR__ . '/out/' . 'adaptiveresizeimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::adaptiveResizeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: The number of columns in the scaled image.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: The number of rows in the scaled image.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to fit the image within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Adaptively resize image with data dependent triangulation

Description: Adaptively resize image with data-dependent triangulation. Avoids blurring across sharp color changes. Most useful when used to shrink images slightly to a slightly smaller "web size"; may not look good when a full-sized image is adaptively resized to a thumbnail. Доступность зависит от версии ImageMagick не ниже 6.2.9. With bestfit enabled the image fits inside the requested box while preserving its aspect ratio.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: Version Description PECL imagick 2.1.0 Added optional fit parameter. PECL imagick 2.1.0 This method now supports proportional scaling. Pass zero as either parameter for proportional scaling. PECL imagick 3.4.0 Added the legacy parameter.

SHA страницы: 9eb7cc02faf366cdbbd0d6810a92adf873d79f281f002ae1f2e3af5be7465059; SHA XML: aa30650adf50654a3badd482c538be68e491b533f4835014ff8d908caceb24c7.

Связи официальной страницы. Imagick::chopImage, Imagick::cropImage, Imagick::magnifyImage, Imagick::minifyImage, Imagick::resizeImage, Imagick::scaleImage, Imagick::shaveImage, Imagick::thumbnailImage, Imagick::trimImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::affineTransformImageОдной матрицей сдвинуть, масштабировать или наклонить отсканированную этикетку.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::affineTransformImage(ImagickDraw $matrix): bool

Реальная потребность. Одной матрицей сдвинуть, масштабировать или наклонить отсканированную этикетку.

Что получится. Изменить координаты пикселей по шести коэффициентам affine matrix.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::affineTransformImage(ImagickDraw $matrix): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::affineTransformImage(ImagickDraw $matrix): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$matrixImagickDraw; обязательныйImagickDraw с шестью коэффициентами affine matrix
Official: The affine matrix

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Перепутанный порядок коэффициентов уводит изображение за холст или делает его пустым. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Матрица не выбирает автоматически новый холст и фон.

Что выбрать рядом. Rotateimage, shearimage или scaleimage, когда нужна одна понятная операция.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: одной матрицей сдвинуть, масштабировать или наклонить отсканированную этикеткуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $draw = new ImagickDraw();
    $draw->affine(['sx' => 1.0, 'rx' => 0.12, 'ry' => 0.0, 'sy' => 1.0, 'tx' => 1.0, 'ty' => 0.0]);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->affineTransformImage($draw);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'affinetransformimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::affineTransformImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: изменить координаты пикселей по шести коэффициентам affine matrixПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $draw = new ImagickDraw();
    $draw->affine(['sx' => 0.9, 'rx' => 0.0, 'ry' => 0.15, 'sy' => 1.0, 'tx' => 0.0, 'ty' => 1.0]);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->affineTransformImage($draw);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'affinetransformimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::affineTransformImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$matrixImagickDraw; обязательныйImagickDraw с шестью коэффициентами affine matrix
Official: The affine matrix
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Transforms an image

Description: Transforms an image as dictated by the affine matrix.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: ef911c3d8870ce174a1ac6144d6e9ffb8e9e7eefe3ae7caea080afc005de1ed0; SHA XML: 6eeeb2119f7bd6ab6d78befc648d46b383ce2822d534d60f7189a43df2617305.

Imagick::chopImageУдалить полосу из середины макета и сдвинуть оставшиеся части друг к другу.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::chopImage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Удалить полосу из середины макета и сдвинуть оставшиеся части друг к другу.

Что получится. Уменьшить холст ровно на вырезанную ширину и высоту.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::chopImage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::chopImage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: Width of the chopped area
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: Height of the chopped area
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: X origo of the chopped area
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: Y origo of the chopped area

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Область вне кадра и неверные координаты дают неожиданный размер. При ошибке выбрасывается ImagickException.

Граница. Chop удаляет полосу, а не оставляет прямоугольный фрагмент.

Что выбрать рядом. Cropimage, если нужно сохранить выбранную область.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: удалить полосу из середины макета и сдвинуть оставшиеся части друг к другуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->chopImage(2, 2, 3, 2);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 10 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'chopimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::chopImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: уменьшить холст ровно на вырезанную ширину и высотуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->chopImage(3, 1, 4, 3);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 9 && $afterGeometry['height'] === 7;
    $artifact = __DIR__ . '/out/' . 'chopimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::chopImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: Width of the chopped area
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: Height of the chopped area
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: X origo of the chopped area
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: Y origo of the chopped area
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Removes a region of an image and trims

Description: Removes a region of an image and collapses the image to occupy the removed portion.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 62fb583f078bb16c04a7dce65ff033719a209ef7cf8bc9e448e1f66e85321248; SHA XML: 41582dc132a8b5af1f32f7ab9c30ec70ba8747cd119686265fab1855d87fd47e.

Связи официальной страницы. Imagick::cropImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::cropImageВырезать карточку товара или нижнюю область документа по известным координатам.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::cropImage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Вырезать карточку товара или нижнюю область документа по известным координатам.

Что получится. Оставить прямоугольник width x height начиная с x,y.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::cropImage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::cropImage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the crop
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The height of the crop
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: The X coordinate of the cropped region's top left corner
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: The Y coordinate of the cropped region's top left corner

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. После crop сохраняется page offset, из-за которого следующий crop/composite может работать не там. При ошибке выбрасывается ImagickException.

Граница. Координаты относятся к текущему пиксельному кадру и требуют проверки границ.

Что выбрать рядом. Cropthumbnailimage для превью фиксированного соотношения; после crop вызвать resetimagepage.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: вырезать карточку товара или нижнюю область документа по известным координатамПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->cropImage(6, 4, 2, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 6 && $afterGeometry['height'] === 4;
    $artifact = __DIR__ . '/out/' . 'cropimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::cropImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: оставить прямоугольник width x height начиная с x,yПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->cropImage(8, 5, 2, 2);
    $checks = ['return_contract' => $result === true];
    $pageBeforeReset = $image->getImagePage();
    $image->resetImagePage('');
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $effect['page_before_reset'] = $pageBeforeReset;
    $effect['page_after_reset'] = $afterPage;
    $checks['page_offset_reset'] = ($afterPage['x'] ?? null) === 0 && ($afterPage['y'] ?? null) === 0;
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 5;
    $artifact = __DIR__ . '/out/' . 'cropimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::cropImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the crop
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The height of the crop
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: The X coordinate of the cropped region's top left corner
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: The Y coordinate of the cropped region's top left corner
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Extracts a region of the image

Description: Extracts a region of the image.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: b3bddcba72f1e6ae72632a507d467753a96776016bc2a476e21388b440c463be; SHA XML: 4b89aa8824730c7b43dfdb260b70d6b53af0bf8711118ace5b8bfcf247909de4.

Imagick::cropThumbnailImageСделать заполняющее квадрат или карточку превью без пустых полей.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::cropThumbnailImage(int $width, int $height, bool $legacy = false): bool

Реальная потребность. Сделать заполняющее квадрат или карточку превью без пустых полей.

Что получится. Масштабировать и обрезать центр до точных width/height.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::cropThumbnailImage(int $width, int $height, bool $legacy = false): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::cropThumbnailImage(int $width, int $height, bool $legacy = false): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the thumbnail
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The Height of the thumbnail
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Важный объект у края кадра может быть срезан. При ошибке выбрасывается ImagickException.

Граница. Метод выбирает центральный crop и не знает область интереса.

Что выбрать рядом. Ручной resize + crop по focal point, если лицо или товар смещён.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: сделать заполняющее квадрат или карточку превью без пустых полейПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->cropThumbnailImage(6, 6, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 6 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'cropthumbnailimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::cropThumbnailImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: масштабировать и обрезать центр до точных width/heightПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->cropThumbnailImage(8, 5, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 5;
    $artifact = __DIR__ . '/out/' . 'cropthumbnailimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::cropThumbnailImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the thumbnail
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The Height of the thumbnail
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creates a crop thumbnail

Description: Creates a fixed size thumbnail by first scaling the image up or down and cropping a specified area from the center.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: Version Description PECL imagick 3.4.0 Added the legacy parameter.

SHA страницы: a72eecd9d30410c54aa3de0570da381d0256b1cb5184f2b71edec61c9e325853; SHA XML: 636e41b83860b02744c09c4fc8cc7d494cb1b69cf9bcf00b1b025244e96261b5.

Imagick::distortImageИсправить перспективу документа или применить заданное геометрическое отображение.

PECL imagick 2 >= 2.0.1, PECL imagick 3 · imagick

Imagick::distortImage(int $method, array $arguments, bool $bestfit): bool

Реальная потребность. Исправить перспективу документа или применить заданное геометрическое отображение.

Что получится. Пересчитать пиксели по выбранному distortion_* и массиву аргументов.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::distortImage(int $method, array $arguments, bool $bestfit): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::distortImage(int $method, array $arguments, bool $bestfit): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$methodint; обязательныйконстанта Imagick::DISTORTION_*
Official: The method of image distortion. See distortion constants
$argumentsarray; обязательныйчисла в порядке, который требует выбранный distortion method
Official: The arguments for this distortion method
$bestfitbool; обязательныйсохранить пропорции и вписать изображение в обе заданные стороны
Official: Attempt to resize destination to fit distorted source

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Число и смысл arguments зависят от метода; неверный набор даёт исключение или бессмысленный кадр. При ошибке выбрасывается ImagickException.

Граница. Bestfit меняет холст и не заменяет проверку page geometry.

Что выбрать рядом. Affinetransformimage для простой affine-матрицы.

Доступность. PECL imagick 2 >= 2.0.1, PECL imagick 3.

Минимальный контрольный пример: исправить перспективу документа или применить заданное геометрическое отображениеПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->distortImage(Imagick::DISTORTION_AFFINEPROJECTION, [1, 0, 0, 1, 1, 1], true);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'distortimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::distortImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: пересчитать пиксели по выбранному DISTORTION_* и массиву аргументовПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->distortImage(Imagick::DISTORTION_AFFINEPROJECTION, [1, 0.12, -0.08, 1, 0, 0], true);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'distortimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::distortImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$methodint; обязательныйконстанта Imagick::DISTORTION_*
Official: The method of image distortion. See distortion constants
$argumentsarray; обязательныйчисла в порядке, который требует выбранный distortion method
Official: The arguments for this distortion method
$bestfitbool; обязательныйсохранить пропорции и вписать изображение в обе заданные стороны
Official: Attempt to resize destination to fit distorted source
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Distorts an image using various distortion methods

Description: Distorts an image using various distortion methods, by mapping color lookups of the source image to a new destination image usually of the same size as the source image, unless 'bestfit' is set to true. If 'bestfit' is enabled, and distortion allows it, the destination image is adjusted to ensure the whole source 'image' will just fit within the final destination image, which will be sized and offset accordingly. Also in many cases the virtual offset of the source image will be taken into account in the mapping. Доступность зависит от версии ImageMagick не ниже 6.3.6.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 998307dbae191fe9b6b29060afc9941261e1b401dabc9d7ffff9576071953e37; SHA XML: 4ee69b590259936934fc69c1169b125d46e1d5de03676eb31ebeb55aa3abfa07.

Связи официальной страницы. Imagick::blurImage, Imagick::motionBlurImage, Imagick::radialBlurImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::extentImageДобавить поля вокруг товара или привести результат к точному размеру холста.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::extentImage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Добавить поля вокруг товара или привести результат к точному размеру холста.

Что получится. Получить canvas заданных width/height и расположить старый кадр по x,y.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::extentImage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::extentImage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The new width
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The new height
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: X position for the new size
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: Y position for the new size

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Знак смещения часто понимают наоборот, а неустановленный background даёт неожиданный цвет. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Extent не масштабирует содержимое.

Что выбрать рядом. Spliceimage для вставки полосы или cropimage для уменьшения.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: добавить поля вокруг товара или привести результат к точному размеру холстаПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#eef2f7'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->extentImage(16, 12, -2, -2);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 16 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'extentimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::extentImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: получить canvas заданных width/height и расположить старый кадр по x,yПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#fff7d6'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->extentImage(18, 10, -3, -1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 18 && $afterGeometry['height'] === 10;
    $artifact = __DIR__ . '/out/' . 'extentimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::extentImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The new width
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The new height
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: X position for the new size
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: Y position for the new size
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Set image size

Description: Comfortability method for setting image size. The method sets the image size and allows setting x,y coordinates where the new area begins. Доступность зависит от версии ImageMagick не ниже 6.3.1. Prior to ImageMagick 6.5.7-8 (1623), $x was positive when shifting to the left and negative when shifting to the right, and $y was positive when shifting an image up and negative when shifting an image down. Somewhere between ImageMagick 6.3.7 (1591) and ImageMagick 6.5.7-8 (1623), the axes of $x and $y were flipped, so that $x was negative when shifting to the left and positive when shifting to the right, and $y was negative when shifting an image up and positive when shifting an image down. Somewhere between ImageMagick 6.5.7-8 (1623) and ImageMagick 6.6.9-7 (1641), the axes of $x and $y were flipped back to pre-ImageMagick 6.5.7-8 (1623) functionality.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 1430d65bf6bbcc5c61db68ec8bbc2a4519ba80bcbe3d922f90742d41e8d4a5a0; SHA XML: 6517fd2648fdfe47e1e03161e44b320f2b159a929ba10ff75718c4a6ab224945.

Связи официальной страницы. Imagick::resizeImage, Imagick::thumbnailImage, Imagick::cropImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::flipImageИсправить вертикально перевёрнутый скан.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::flipImage(): bool

Реальная потребность. Исправить вертикально перевёрнутый скан.

Что получится. Поменять местами верх и низ, сохранив width/height.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::flipImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::flipImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. На симметричном изображении эффект невозможно проверить на глаз. При ошибке выбрасывается ImagickException.

Граница. Операция меняет пиксели, но не решает exif orientation автоматически.

Что выбрать рядом. Autoorientimage для ориентации камеры или flopimage для лево/право.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: исправить вертикально перевёрнутый сканПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->flipImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['control_corner_changed'] = $afterCorner !== $before['corner'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'flipimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::flipImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: поменять местами верх и низ, сохранив width/heightПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->flipImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['control_corner_changed'] = $afterCorner !== $before['corner'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'flipimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::flipImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creates a vertical mirror image

Description: Creates a vertical mirror image by reflecting the pixels around the central x-axis.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 2ddb16055c6b2b7733ff407031b509612f7f7d0b8cbbc5c057206f67098b5ab3; SHA XML: 8cb957dad845a2df3813180d99dc7c95818c917d135973c433064e1fa2b522cf.

Связи официальной страницы. Imagick::flopimage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::flopImageСделать горизонтальное зеркало схемы или исправить зеркальный кадр.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::flopImage(): bool

Реальная потребность. Сделать горизонтальное зеркало схемы или исправить зеркальный кадр.

Что получится. Поменять местами левую и правую стороны.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::flopImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::flopImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Текст также станет зеркальным. При ошибке выбрасывается ImagickException.

Граница. Ширина и высота остаются прежними, поэтому проверяют контрольные цвета по углам.

Что выбрать рядом. Flipimage для верх/низ.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: сделать горизонтальное зеркало схемы или исправить зеркальный кадрПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->flopImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['control_corner_changed'] = $afterCorner !== $before['corner'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'flopimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::flopImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: поменять местами левую и правую стороныПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->flopImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['control_corner_changed'] = $afterCorner !== $before['corner'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'flopimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::flopImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creates a horizontal mirror image

Description: Creates a horizontal mirror image by reflecting the pixels around the central y-axis.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 1e9f6cbc13110a8e0285c38650403bf8dbe065eebc7e1871b060c60c3bb6b68f; SHA XML: 2d4c23e4f8b3d1e5a12436140105be7644288a0199e51fb316e49b01f244edf9.

Связи официальной страницы. Imagick::flipimage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::getImageGeometryПолучить width и height одним вызовом перед crop или лимитом пикселей.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageGeometry(): array

Реальная потребность. Получить width и height одним вызовом перед crop или лимитом пикселей.

Что получится. Вернуть массив с фактическими размерами текущего кадра.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::getImageGeometry(): array либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::getImageGeometry(): array; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: array. Возвращается массив. В примере проверяются конкретные ключи или число элементов, а не только сам тип.

Когда ломается. Пустой объект или невыбранный кадр приводит к исключению. При ошибке выбрасывается ImagickException.

Граница. Geometry пикселей не равна page geometry и не сообщает compressed bytes.

Что выбрать рядом. Getimagewidth/getimageheight для одного измерения; getimagepage для virtual canvas.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: получить width и height одним вызовом перед crop или лимитом пикселейПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageGeometry();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageGeometry',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть массив с фактическими размерами текущего кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageGeometry();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageGeometry',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Gets the width and height as an associative array

Description: Returns the width and height as an associative array.

Return: Returns an array with the width/height of the image.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: fe3be433c5736b6c290e0257804427e66a49476fe1365d7b5718d847a57a720f; SHA XML: 465008de90371995604ad72443f0482aa3d1c8d98ae9ceaa2fade2c542746343.

Imagick::getImageHeightПроверить высоту загруженного изображения до дорогой обработки.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageHeight(): int

Реальная потребность. Проверить высоту загруженного изображения до дорогой обработки.

Что получится. Вернуть число строк пикселей текущего кадра.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::getImageHeight(): int либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::getImageHeight(): int; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: int. Возвращается целое число; его единицы и границы названы в карточке.

Когда ломается. В последовательности значение относится только к текущему кадру. При ошибке выбрасывается ImagickException.

Граница. Высота в пикселях не равна физической высоте печати без resolution.

Что выбрать рядом. Getimagegeometry для пары width/height.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: проверить высоту загруженного изображения до дорогой обработкиПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageHeight();
    $checks = ['return_contract' => is_int($result)];
    $effect = ['value' => $result];
    $checks['non_negative'] = $result >= 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageHeight',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть число строк пикселей текущего кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageHeight();
    $checks = ['return_contract' => is_int($result)];
    $effect = ['value' => $result];
    $checks['non_negative'] = $result >= 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageHeight',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Returns the image height

Description: Returns the image height.

Return: Returns the image height in pixels.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: fdecd1e0f77151d7ba3aebe65f2e82f630b35b3f9e15dd2b91cc0247c453ac45; SHA XML: 7a17169ff4a648c998cb73eae04c38b159af0136ab61a3e84b989edec0c14787.

Imagick::getImagePageУвидеть virtual canvas и offset текущего кадра после crop/trim.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImagePage(): array

Реальная потребность. Увидеть virtual canvas и offset текущего кадра после crop/trim.

Что получится. Вернуть width, height, x и y page geometry изображения.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::getImagePage(): array либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::getImagePage(): array; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: array. Возвращается массив. В примере проверяются конкретные ключи или число элементов, а не только сам тип.

Когда ломается. Page size можно ошибочно принять за размер пиксельного растра. При ошибке выбрасывается ImagickException.

Граница. Offset способен сохраниться после crop и влиять на следующую операцию.

Что выбрать рядом. Getimagegeometry для пикселей; resetimagepage для нормализации.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: увидеть virtual canvas и offset текущего кадра после crop/trimПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, 3, 2);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImagePage();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть width, height, x и y page geometry изображенияПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, -2, 4);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImagePage();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Returns the page geometry

Description: Returns the page geometry associated with the image in an array with the keys "width", "height", "x", and "y".

Return: Returns the page geometry associated with the image in an array with the keys "width", "height", "x", and "y".

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 56d1e439affe0241dda21d3c6e966d5c5c2ec0a2f692cd354a47dfa103c4ab87; SHA XML: 0635054a369d5db62353e6149b9bbaddbd32dd47b3f1bba8c86735b2d663e4af.

Imagick::getImageWidthПроверить ширину до вычисления масштаба, crop или лимита area.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageWidth(): int

Реальная потребность. Проверить ширину до вычисления масштаба, crop или лимита area.

Что получится. Вернуть число столбцов пикселей текущего кадра.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::getImageWidth(): int либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::getImageWidth(): int; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: int. Возвращается целое число; его единицы и границы названы в карточке.

Когда ломается. В gif/tiff каждый кадр может иметь свою ширину. При ошибке выбрасывается ImagickException.

Граница. Значение не показывает page canvas, dpi и память.

Что выбрать рядом. Getimagegeometry для обеих сторон.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: проверить ширину до вычисления масштаба, crop или лимита areaПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageWidth();
    $checks = ['return_contract' => is_int($result)];
    $effect = ['value' => $result];
    $checks['non_negative'] = $result >= 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageWidth',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть число столбцов пикселей текущего кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getImageWidth();
    $checks = ['return_contract' => is_int($result)];
    $effect = ['value' => $result];
    $checks['non_negative'] = $result >= 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getImageWidth',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Returns the image width

Description: Returns the image width.

Return: Returns the image width.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 519b8e833136458789ea23b262729cda51b2fe919de8eddbad79e402226073ce; SHA XML: 60221b039724b3efd358e7927f20ae20dfc73808546ee804333e98f963ee8d02.

Imagick::getPageПроверить объектную page geometry до операции, использующей virtual canvas.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getPage(): array

Реальная потребность. Проверить объектную page geometry до операции, использующей virtual canvas.

Что получится. Вернуть объектные width, height, x и y.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::getPage(): array либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::getPage(): array; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: array. Возвращается массив. В примере проверяются конкретные ключи или число элементов, а не только сам тип.

Когда ломается. Объектную настройку легко спутать с page текущего кадра. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Различие getpage/getimagepage зависит от уровня состояния imagick/imagemagick.

Что выбрать рядом. Getimagepage для текущего изображения.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: проверить объектную page geometry до операции, использующей virtual canvasПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setPage(20, 16, 3, 2);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getPage();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getPage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть объектные width, height, x и yПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setPage(20, 16, -2, 4);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->getPage();
    $checks = ['return_contract' => is_array($result)];
    $effect = ['geometry' => $result];
    $checks['geometry_keys'] = isset($result['width'], $result['height']);
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::getPage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Returns the page geometry

Description: Returns the page geometry associated with the Imagick object in an associative array with the keys "width", "height", "x", and "y".

Return: Returns the page geometry associated with the Imagick object in an associative array with the keys "width", "height", "x", and "y", throwing ImagickException on error.

Errors: —

Changelog: —

SHA страницы: b1a78e1d83db91cce5902b0dd47cccfaa957d9b374054c30c90b52bf4a1e9a77; SHA XML: 22ca4ea2a8f6115da433db6704c3a69fc9b7cbc8bc68ac52e98b98431cfadb06.

Imagick::liquidRescaleImageСжать панораму по ширине, стараясь меньше деформировать заметные детали.

PECL imagick 2 >= 2.2.0, PECL imagick 3 · imagick

Imagick::liquidRescaleImage(int $width, int $height, float $delta_x, float $rigidity): bool

Реальная потребность. Сжать панораму по ширине, стараясь меньше деформировать заметные детали.

Что получится. Удалить или добавить seam-пути до целевого размера.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::liquidRescaleImage(int $width, int $height, float $delta_x, float $rigidity): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::liquidRescaleImage(int $width, int $height, float $delta_x, float $rigidity): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the target size
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The height of the target size
$delta_xfloat; обязательныйдопустимое боковое движение seam; 0 делает seam прямее
Official: How much the seam can traverse on x-axis. Passing 0 causes the seams to be straight.
$rigidityfloat; обязательныйштраф за изгиб seam; обычно начинают с 0
Official: Introduces a bias for non-straight seams. This parameter is typically 0.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Delegate liquid-rescale может отсутствовать, а лица и прямые линии всё равно искажаются. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Операция значительно дороже обычного resize и требует визуального контроля.

Что выбрать рядом. Resizeimage или управляемый crop по focal point.

Доступность. PECL imagick 2 >= 2.2.0, PECL imagick 3.

Минимальный контрольный пример: сжать панораму по ширине, стараясь меньше деформировать заметные деталиПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->liquidRescaleImage(8, 6, 0.0, 0.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'liquidrescaleimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::liquidRescaleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: удалить или добавить seam-пути до целевого размераПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->liquidRescaleImage(9, 6, 1.0, 0.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 9 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'liquidrescaleimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::liquidRescaleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: The width of the target size
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: The height of the target size
$delta_xfloat; обязательныйдопустимое боковое движение seam; 0 делает seam прямее
Official: How much the seam can traverse on x-axis. Passing 0 causes the seams to be straight.
$rigidityfloat; обязательныйштраф за изгиб seam; обычно начинают с 0
Official: Introduces a bias for non-straight seams. This parameter is typically 0.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Animates an image or images

Description: This method scales the images using liquid rescaling method. This method is an implementation of a technique called seam carving. In order for this method to work as expected ImageMagick must be compiled with liblqr support. Доступность зависит от версии ImageMagick не ниже 6.3.9.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 7c4a4a35eba60bd04e2767e80f24937fcc6ef61f31c24eac563168ca0ba3bb97; SHA XML: 32ade86cfaf3a5f12dcb24f9b1865a222d1b4aefdf2413d0df91e49e54fff758.

Связи официальной страницы. Imagick::resizeImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::magnifyImageБыстро получить увеличенную вдвое диагностическую копию маленького растра.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::magnifyImage(): bool

Реальная потребность. Быстро получить увеличенную вдвое диагностическую копию маленького растра.

Что получится. Увеличить текущий кадр встроенным фиксированным алгоритмом.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::magnifyImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::magnifyImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Детали не появляются, а артефакты и память растут. При ошибке выбрасывается ImagickException.

Граница. Коэффициент и фильтр не настраиваются.

Что выбрать рядом. Resizeimage для точного размера и фильтра.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: быстро получить увеличенную вдвое диагностическую копию маленького растраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->magnifyImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 24 && $afterGeometry['height'] === 16;
    $artifact = __DIR__ . '/out/' . 'magnifyimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::magnifyImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: увеличить текущий кадр встроенным фиксированным алгоритмомПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->magnifyImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 24 && $afterGeometry['height'] === 16;
    $artifact = __DIR__ . '/out/' . 'magnifyimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::magnifyImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Scales an image proportionally 2x

Description: Is a convenience method that scales an image proportionally to twice its original size.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 621a9e68127ed635fd22cb409c1a5ba1db4e97c3fe8d45f29c65f03e69b8b863; SHA XML: 5e8f1320ae2e99f062942eb9290b1afe7ccff63a1cdaadf8687fb4f48376e328.

Imagick::minifyImageБыстро получить уменьшенную вдвое черновую копию.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::minifyImage(): bool

Реальная потребность. Быстро получить уменьшенную вдвое черновую копию.

Что получится. Сократить width и height приблизительно в два раза.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::minifyImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::minifyImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Нечётные размеры округляются, а точного target box задать нельзя. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Фильтр и итоговый размер не настраиваются.

Что выбрать рядом. Thumbnailimage или resizeimage для production-превью.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: быстро получить уменьшенную вдвое черновую копиюПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->minifyImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 6 && $afterGeometry['height'] === 4;
    $artifact = __DIR__ . '/out/' . 'minifyimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::minifyImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: сократить width и height приблизительно в два разаПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->minifyImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 6 && $afterGeometry['height'] === 4;
    $artifact = __DIR__ . '/out/' . 'minifyimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::minifyImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Scales an image proportionally to half its size

Description: Is a convenience method that scales an image proportionally to one-half its original size

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: ccccd07f7963a7b5b5e1f708981118ef034429ca3fc9e2f26da4e520e0891be7; SHA XML: 4e9bbd9198059930a4da2bb006a53ffc5c2568461ba04228760083905b96dcfd.

Imagick::resampleImageПересчитать пиксели при смене печатного разрешения, а не просто переписать dpi-метку.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::resampleImage(float $x_resolution, float $y_resolution, int $filter, float $blur): bool

Реальная потребность. Пересчитать пиксели при смене печатного разрешения, а не просто переписать dpi-метку.

Что получится. Изменить размер пикселей относительно исходного и нового resolution выбранным фильтром.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::resampleImage(float $x_resolution, float $y_resolution, int $filter, float $blur): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::resampleImage(float $x_resolution, float $y_resolution, int $filter, float $blur): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$x_resolutionfloat; обязательныйцелевое горизонтальное resolution
Official: В frozen official page отдельное описание отсутствует.
$y_resolutionfloat; обязательныйцелевое вертикальное resolution
Official: В frozen official page отдельное описание отсутствует.
$filterint; обязательныйконстанта Imagick::FILTER_* для resampling
Official: В frozen official page отдельное описание отсутствует.
$blurfloat; обязательныйкоэффициент blur фильтра; 1.0 — нейтральная отправная точка
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Если исходный resolution не задан или неверен, итоговая геометрия неожиданна. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Dpi сам по себе не улучшает детализацию; resample создаёт или удаляет пиксели.

Что выбрать рядом. Setimageresolution, если нужна только корректная метка без resampling.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: пересчитать пиксели при смене печатного разрешения, а не просто переписать DPI-меткуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImageResolution(72.0, 72.0);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resampleImage(144.0, 144.0, Imagick::FILTER_LANCZOS, 1.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'resampleimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resampleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: изменить размер пикселей относительно исходного и нового resolution выбранным фильтромПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImageResolution(300.0, 300.0);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resampleImage(150.0, 150.0, Imagick::FILTER_LANCZOS, 1.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'resampleimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resampleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$x_resolutionfloat; обязательныйцелевое горизонтальное resolution
Official: В frozen official page отдельное описание отсутствует.
$y_resolutionfloat; обязательныйцелевое вертикальное resolution
Official: В frozen official page отдельное описание отсутствует.
$filterint; обязательныйконстанта Imagick::FILTER_* для resampling
Official: В frozen official page отдельное описание отсутствует.
$blurfloat; обязательныйкоэффициент blur фильтра; 1.0 — нейтральная отправная точка
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Resample image to desired resolution

Description: Resample image to desired resolution.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: fe5495dbd6fa6a42e7300ce50a23c652330890eee5df1197ac2f51037c261793; SHA XML: c96d51272077b938305682aa23a2a217fd94aa665ec3372b15ad94b4f662aa34.

Imagick::resetImagePageПосле crop или trim убрать старый canvas offset перед повторной геометрией.

PECL imagick 2 >= 2.3.0, PECL imagick 3 · imagick

Imagick::resetImagePage(string $page): bool

Реальная потребность. После crop или trim убрать старый canvas offset перед повторной геометрией.

Что получится. Назначить новую page geometry строкой и сделать координаты дальнейших операций предсказуемыми.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::resetImagePage(string $page): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::resetImagePage(string $page): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$pagestring; обязательныйстрока ImageMagick geometry: размер и смещение
Official: The page definition. For example 7168x5147+0+0

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Неверная geometry string вызывает исключение или сохраняет ненужный offset. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Метод не меняет сами пиксели.

Что выбрать рядом. Setimagepage с явными четырьмя числами.

Доступность. PECL imagick 2 >= 2.3.0, PECL imagick 3.

Минимальный контрольный пример: после crop или trim убрать старый canvas offset перед повторной геометриейПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, 3, 2);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resetImagePage('6x4+0+0');
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['page'];
    $checks['page_contract'] = $afterPage['width'] === 6 && $afterPage['height'] === 4 && $afterPage['x'] === 0 && $afterPage['y'] === 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resetImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: назначить новую page geometry строкой и сделать координаты дальнейших операций предсказуемымиПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, -2, 4);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resetImagePage('8x5+0+0');
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['page'];
    $checks['page_contract'] = $afterPage['width'] === 8 && $afterPage['height'] === 5 && $afterPage['x'] === 0 && $afterPage['y'] === 0;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resetImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$pagestring; обязательныйстрока ImageMagick geometry: размер и смещение
Official: The page definition. For example 7168x5147+0+0
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Reset image page

Description: The page definition as a string. The string is in format WxH+x+y. Доступность зависит от версии ImageMagick не ниже 6.3.6.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 2942b0312c97e341759a7b0273bc03330688dcd2989993dc935329f4ac35faab; SHA XML: 6e308f7174a543e4693d3fcb3bbd68901c7fcfa8449d2284222304508c0d9411.

Imagick::resizeImageСоздать веб-версию фотографии с выбранным фильтром и контролем пропорций.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::resizeImage(int $columns, int $rows, int $filter, float $blur, bool $bestfit = false, bool $legacy = false): bool

Реальная потребность. Создать веб-версию фотографии с выбранным фильтром и контролем пропорций.

Что получится. Пересчитать пиксели до заданных columns/rows.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::resizeImage(int $columns, int $rows, int $filter, float $blur, bool $bestfit = false, bool $legacy = false): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::resizeImage(int $columns, int $rows, int $filter, float $blur, bool $bestfit = false, bool $legacy = false): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: Width of the image
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: Height of the image
$filterint; обязательныйконстанта Imagick::FILTER_* для resampling
Official: Refer to the list of filter constants .
$blurfloat; обязательныйкоэффициент blur фильтра; 1.0 — нейтральная отправная точка
Official: The blur factor where > 1 is blurry, < 1 is sharp.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Optional bool parameter. If set to true, the image is resized to fit within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Bestfit с нулевой стороной, отрицательные размеры и огромный decode приводят к ошибке. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Filter и blur влияют на качество/скорость; resize не удаляет metadata и не задаёт формат.

Что выбрать рядом. Thumbnailimage для облегчённого превью или scaleimage для простого масштаба.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: создать веб-версию фотографии с выбранным фильтром и контролем пропорцийПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resizeImage(6, 4, Imagick::FILTER_LANCZOS, 1.0, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 6 && $afterGeometry['height'] <= 4;
    $artifact = __DIR__ . '/out/' . 'resizeimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resizeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: пересчитать пиксели до заданных columns/rowsПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->resizeImage(8, 5, Imagick::FILTER_MITCHELL, 1.0, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 8 && $afterGeometry['height'] <= 5;
    $artifact = __DIR__ . '/out/' . 'resizeimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::resizeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: Width of the image
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: Height of the image
$filterint; обязательныйконстанта Imagick::FILTER_* для resampling
Official: Refer to the list of filter constants .
$blurfloat; обязательныйкоэффициент blur фильтра; 1.0 — нейтральная отправная точка
Official: The blur factor where > 1 is blurry, < 1 is sharp.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Optional bool parameter. If set to true, the image is resized to fit within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Scales an image

Description: Scales an image to the desired dimensions with a filter . With bestfit enabled the image fits inside the requested box while preserving its aspect ratio.

Return: Returns true on success.

Errors: —

Changelog: Version Description PECL imagick 2.1.0 Added optional fit parameter. This method now supports proportional scaling. Pass zero as either parameter for proportional scaling. PECL imagick 3.4.0 Added the legacy parameter.

SHA страницы: 3c8bbcd772c115ef1699e4cdcc1890e43bf3648d6df9fa3be192c3ca2b37cc8e; SHA XML: 63d81f58a58172fda8cb48e3bf277d7d688a346951693ebb4359822b6cb264f3.

Imagick::rollImageЦиклически сместить бесшовную текстуру и проверить стык.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::rollImage(int $x, int $y): bool

Реальная потребность. Циклически сместить бесшовную текстуру и проверить стык.

Что получится. Перенести вышедшие за край пиксели на противоположную сторону.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::rollImage(int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::rollImage(int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: The X offset.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: The Y offset.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Roll не добавляет фон: данные заворачиваются, что неверно для обычного позиционирования. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Offset берётся в пикселях и допускает отрицательные значения.

Что выбрать рядом. Extentimage/compositeimage для сдвига с пустым фоном.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: циклически сместить бесшовную текстуру и проверить стыкПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->rollImage(2, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'rollimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::rollImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: перенести вышедшие за край пиксели на противоположную сторонуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->rollImage(-3, 2);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry === $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'rollimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::rollImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: The X offset.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: The Y offset.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Offsets an image

Description: Offsets an image as defined by x and y.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 71bc2d191516b27f9acb1e65cc5bfd5c16a9b49e0988ea8fc12317bc9d22ef9f; SHA XML: 38b3fd64054adc5e83bed51a40122866b9007938388bc0f1929a6c1c946e5a1e.

Imagick::rotateImageПовернуть скан или пользовательскую фотографию на заданный угол.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::rotateImage(mixed $background, float $degrees): bool

Реальная потребность. Повернуть скан или пользовательскую фотографию на заданный угол.

Что получится. Создать повернутый растр и заполнить появившиеся углы выбранным background.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::rotateImage(mixed $background, float $degrees): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::rotateImage(mixed $background, float $degrees): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$backgroundmixed; обязательныйцвет пикселей, появившихся за исходным кадром
Official: The background color
$degreesfloat; обязательныйугол по часовой стрелке в градусах
Official: Rotation angle, in degrees. The rotation angle is interpreted as the number of degrees to rotate the image clockwise.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Прозрачный фон потеряется при последующей записи в jpeg. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Для произвольного угла меняется bounding box, а exif orientation сам не сбрасывается.

Что выбрать рядом. Autoorientimage для метаданных камеры; transpose/transverse для точных 90°+mirror.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: повернуть скан или пользовательскую фотографию на заданный уголПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->rotateImage(new ImagickPixel('transparent'), 90.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'rotateimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::rotateImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: создать повернутый растр и заполнить появившиеся углы выбранным backgroundПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->rotateImage(new ImagickPixel('#f2f4f7'), 15.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'rotateimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::rotateImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$backgroundmixed; обязательныйцвет пикселей, появившихся за исходным кадром
Official: The background color
$degreesfloat; обязательныйугол по часовой стрелке в градусах
Official: Rotation angle, in degrees. The rotation angle is interpreted as the number of degrees to rotate the image clockwise.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Rotates an image

Description: Rotates an image the specified number of degrees. Empty triangles left over from rotating the image are filled with the background color.

Return: Returns true on success.

Errors: —

Changelog: Version Description PECL imagick 2.1.0 Now allows a string representing the color as the first parameter. Previous versions allow only an ImagickPixel object.

SHA страницы: b305b28c58619eeb38805043158c26f046f1cc76cd1368e89925800b1aad9f45; SHA XML: a1013d764acaa29d4fff5f468c4be4e7eb359ac7575a4ee6accfa18d96dee3c1.

Imagick::sampleImageСделать пиксельное превью или nearest-neighbour масштаб без смешивания цветов.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::sampleImage(int $columns, int $rows): bool

Реальная потребность. Сделать пиксельное превью или nearest-neighbour масштаб без смешивания цветов.

Что получится. Взять ближайшие образцы до заданного размера.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::sampleImage(int $columns, int $rows): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::sampleImage(int $columns, int $rows): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Фотография получит ступени и aliasing. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Sample выбирает пиксели без качественной фильтрации.

Что выбрать рядом. Resizeimage с filter_lanczos для фотографий.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: сделать пиксельное превью или nearest-neighbour масштаб без смешивания цветовПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->sampleImage(6, 4);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 6 && $afterGeometry['height'] === 4;
    $artifact = __DIR__ . '/out/' . 'sampleimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::sampleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: взять ближайшие образцы до заданного размераПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->sampleImage(8, 5);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 5;
    $artifact = __DIR__ . '/out/' . 'sampleimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::sampleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Scales an image with pixel sampling

Description: Scales an image to the desired dimensions with pixel sampling. Unlike other scaling methods, this method does not introduce any additional color into the scaled image.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 8682fca2fd5e392cc47ff6b8db5db34779b38776b2c50bcc5fc9eefcaaeaaeb1; SHA XML: 5059086b1b26bf0efe19b02c5bb17db9adb94ebb330030cd8be4a5b6e895bd6b.

Imagick::scaleImageБыстро изменить размер, когда точный выбор фильтра не нужен.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::scaleImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool

Реальная потребность. Быстро изменить размер, когда точный выбор фильтра не нужен.

Что получится. Масштабировать до columns/rows с возможным bestfit.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::scaleImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::scaleImage(int $columns, int $rows, bool $bestfit = false, bool $legacy = false): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: The number of columns in the scaled image.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: The number of rows in the scaled image.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to fit the image within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Bestfit и нулевая сторона образуют недопустимую geometry в некоторых версиях. При ошибке выбрасывается ImagickException.

Граница. Контроль качества меньше, чем у resizeimage.

Что выбрать рядом. Resizeimage для явного filter/blur.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: быстро изменить размер, когда точный выбор фильтра не нуженПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->scaleImage(6, 4, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 6 && $afterGeometry['height'] <= 4;
    $artifact = __DIR__ . '/out/' . 'scaleimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::scaleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: масштабировать до columns/rows с возможным bestfitПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->scaleImage(8, 5, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 8 && $afterGeometry['height'] <= 5;
    $artifact = __DIR__ . '/out/' . 'scaleimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::scaleImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: The number of columns in the scaled image.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: The number of rows in the scaled image.
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to fit the image within the given dimensions while preserving the aspect ratio.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Optional bool parameter. If set to true, the calculations are done with the small rounding bug that existed in Imagick before 3.4.0. If set to false, the calculations should produce the same results as the ImageMagick command-line tools.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Scales the size of an image

Description: Scales the size of an image to the given dimensions. The other parameter will be calculated if 0 is passed as either param. With bestfit enabled the image fits inside the requested box while preserving its aspect ratio.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: Version Description PECL imagick 2.1.0 Added optional fit parameter. This method now supports proportional scaling. Pass zero as either parameter for proportional scaling. PECL imagick 3.4.0 Added the legacy parameter.

SHA страницы: 154bb68ecd5ef51347908f522f632b17eaa26fd233f06a660e14bbf7b0e54757; SHA XML: 765e0e6478724991a134470fdeb9e37c41bcdeeae6064713e9f16bbabe080287.

Imagick::setImageExtentОбрезать или расширить pixel storage до точных dimensions перед импортом/экспортом.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageExtent(int $columns, int $rows): bool

Реальная потребность. Обрезать или расширить pixel storage до точных dimensions перед импортом/экспортом.

Что получится. Изменить физический extent текущего кадра.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::setImageExtent(int $columns, int $rows): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::setImageExtent(int $columns, int $rows): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Новые области зависят от background/virtual pixels, а старый page offset может сохраниться. При ошибке выбрасывается ImagickException.

Граница. Это низкоуровневое изменение размера, не масштабирование.

Что выбрать рядом. Extentimage для контролируемого canvas с offset.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: обрезать или расширить pixel storage до точных dimensions перед импортом/экспортомПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#eef2f7'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setImageExtent(16, 12);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 16 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'setimageextent-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setImageExtent',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: изменить физический extent текущего кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#fff7d6'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setImageExtent(14, 10);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 14 && $afterGeometry['height'] === 10;
    $artifact = __DIR__ . '/out/' . 'setimageextent-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setImageExtent',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Sets the image size

Description: Sets the image size (i.e. columns [amp] rows).

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: f7ac1f66a1dbad55c4612ad0ef660ecb48e4abc465f14a89e65dfff7c507013e; SHA XML: 7d5d4f7ca7d363393454b0449253ed6462ac6eec62058a32262e567e947c09f6.

Imagick::setImagePageЯвно задать virtual canvas текущего кадра после crop или перед анимацией.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImagePage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Явно задать virtual canvas текущего кадра после crop или перед анимацией.

Что получится. Установить width, height и offset x/y у изображения.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::setImagePage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::setImagePage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Неверный offset сдвигает последующую композицию и кадры. При ошибке выбрасывается ImagickException.

Граница. Метод меняет геометрию страницы, но не массив пикселей.

Что выбрать рядом. Resetimagepage для сброса к новой geometry string.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: явно задать virtual canvas текущего кадра после crop или перед анимациейПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, 3, 2);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setImagePage(12, 8, 2, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['page'];
    $checks['page_contract'] = $afterPage['width'] === 12 && $afterPage['height'] === 8 && $afterPage['x'] === 2 && $afterPage['y'] === 1;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: установить width, height и offset x/y у изображенияПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImagePage(20, 16, -2, 4);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setImagePage(12, 8, -1, 2);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['page'];
    $checks['page_contract'] = $afterPage['width'] === 12 && $afterPage['height'] === 8 && $afterPage['x'] === -1 && $afterPage['y'] === 2;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setImagePage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Sets the page geometry of the image

Description: Sets the page geometry of the image.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 44294e37c65b94083dd0fa63ff21c447b11c3249ca13cf897e7df67730fb80ba; SHA XML: 1ff23a60d961abbe6a11757d13760176c4d4e0a13a703849fb4b8192dc0f577a.

Imagick::setPageЗадать page geometry на уровне объекта перед чтением/созданием результата.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setPage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Задать page geometry на уровне объекта перед чтением/созданием результата.

Что получится. Сохранить объектные width, height, x и y для последующих операций.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::setPage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::setPage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Ожидание немедленного resize приводит к ложной проверке. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Setpage не изменяет физические размеры текущего кадра.

Что выбрать рядом. Setimagepage для выбранного изображения.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: задать page geometry на уровне объекта перед чтением/созданием результатаПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setPage(20, 16, 3, 2);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setPage(12, 8, 2, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getPage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['object_page'];
    $checks['page_contract'] = $afterPage['width'] === 12 && $afterPage['height'] === 8 && $afterPage['x'] === 2 && $afterPage['y'] === 1;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setPage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: сохранить объектные width, height, x и y для последующих операцийПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setPage(20, 16, -2, 4);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->setPage(12, 8, -1, 2);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getPage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['page_observed'] = $afterPage !== $before['object_page'];
    $checks['page_contract'] = $afterPage['width'] === 12 && $afterPage['height'] === 8 && $afterPage['x'] === -1 && $afterPage['y'] === 2;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::setPage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Sets the page geometry of the Imagick object

Description: Sets the page geometry of the Imagick object.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 0463018c75c1357317895e6d5f2cc73528eb8c5b8dc78542e7609caf80d0f295; SHA XML: 2e48616e31ddcc14ff7dbe6e324d26693c6e526e07102a6562b59dc1ecb81d42.

Imagick::shaveImageРавномерно удалить техническую рамку со всех четырёх сторон.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::shaveImage(int $columns, int $rows): bool

Реальная потребность. Равномерно удалить техническую рамку со всех четырёх сторон.

Что получится. Уменьшить ширину на 2*columns и высоту на 2*rows.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::shaveImage(int $columns, int $rows): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::shaveImage(int $columns, int $rows): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Слишком большие значения удалят весь полезный кадр или вызовут ошибку. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Рамка должна быть одинаковой со всех сторон.

Что выбрать рядом. Cropimage для несимметричной области или trimimage для одноцветной рамки.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: равномерно удалить техническую рамку со всех четырёх сторонПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->shaveImage(1, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 10 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'shaveimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::shaveImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: уменьшить ширину на 2*columns и высоту на 2*rowsПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->shaveImage(2, 1);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'shaveimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::shaveImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: В frozen official page отдельное описание отсутствует.
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Shaves pixels from the image edges

Description: Shaves pixels from the image edges. It allocates the memory necessary for the new Image structure and returns a pointer to the new image.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 75649e15ce1959df47ae09ea76c3c15a43c95decc481c4f5964306c08865aaa3; SHA XML: 3580f7cf63678072422abb65a356582257bf88ca0b6acb22bb06eeeca0e15d3f.

Imagick::shearImageНаклонить текстовый блок или компенсировать косой скан по осям.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::shearImage(mixed $background, float $x_shear, float $y_shear): bool

Реальная потребность. Наклонить текстовый блок или компенсировать косой скан по осям.

Что получится. Сдвинуть строки/столбцы на углы x_shear и y_shear с указанным фоном.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::shearImage(mixed $background, float $x_shear, float $y_shear): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::shearImage(mixed $background, float $x_shear, float $y_shear): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$backgroundmixed; обязательныйцвет пикселей, появившихся за исходным кадром
Official: The background color
$x_shearfloat; обязательныйугол наклона по оси X в градусах
Official: The number of degrees to shear on the x axis
$y_shearfloat; обязательныйугол наклона по оси Y в градусах
Official: The number of degrees to shear on the y axis

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Большой угол резко расширяет холст и создаёт пустые клинья. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Shear не исправляет перспективу четырёх произвольных углов.

Что выбрать рядом. Distortimage perspective для документа.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: наклонить текстовый блок или компенсировать косой скан по осямПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->shearImage(new ImagickPixel('transparent'), 12.0, 0.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'shearimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::shearImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: сдвинуть строки/столбцы на углы x_shear и y_shear с указанным фономПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->shearImage(new ImagickPixel('#ffffff'), 0.0, 8.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $artifact = __DIR__ . '/out/' . 'shearimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::shearImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$backgroundmixed; обязательныйцвет пикселей, появившихся за исходным кадром
Official: The background color
$x_shearfloat; обязательныйугол наклона по оси X в градусах
Official: The number of degrees to shear on the x axis
$y_shearfloat; обязательныйугол наклона по оси Y в градусах
Official: The number of degrees to shear on the y axis
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creating a parallelogram

Description: Slides one edge of an image along the X or Y axis, creating a parallelogram. An X direction shear slides an edge along the X axis, while a Y direction shear slides an edge along the Y axis. The amount of the shear is controlled by a shear angle. For X direction shears, x_shear is measured relative to the Y axis, and similarly, for Y direction shears y_shear is measured relative to the X axis. Empty triangles left over from shearing the image are filled with the background color.

Return: Returns true on success.

Errors: —

Changelog: Version Description PECL imagick 2.1.0 Now allows a string representing the color as the first parameter. Previous versions allow only an ImagickPixel object.

SHA страницы: 8a8715e03ed2360dce696fd14a3af068ba735487fdf6a284a22cba255a7234af; SHA XML: ebd76dda45a485623410843e60339cbd46e899e8ddf6ac6c8dba41358282f4a6.

Imagick::spliceImageВставить пустую полосу под подпись или разделитель внутри макета.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::spliceImage(int $width, int $height, int $x, int $y): bool

Реальная потребность. Вставить пустую полосу под подпись или разделитель внутри макета.

Что получится. Раздвинуть пиксели и добавить область width x height в x,y.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::spliceImage(int $width, int $height, int $x, int $y): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::spliceImage(int $width, int $height, int $x, int $y): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Неустановленный background и координаты вне кадра дают неожиданный результат. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Splice вставляет пространство, но не рисует содержимое.

Что выбрать рядом. Extentimage для полей по краям; compositeimage для вставки готового слоя.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: вставить пустую полосу под подпись или разделитель внутри макетаПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#eef2f7'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->spliceImage(2, 2, 4, 3);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 14 && $afterGeometry['height'] === 10;
    $artifact = __DIR__ . '/out/' . 'spliceimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::spliceImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: раздвинуть пиксели и добавить область width x height в x,yПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->setImageBackgroundColor(new ImagickPixel('#fff7d6'));
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->spliceImage(3, 1, 2, 5);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 15 && $afterGeometry['height'] === 9;
    $artifact = __DIR__ . '/out/' . 'spliceimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::spliceImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$widthint; обязательныйширина прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$heightint; обязательныйвысота прямоугольника/холста в пикселях
Official: В frozen official page отдельное описание отсутствует.
$xint; обязательныйгоризонтальная координата от левого края текущего raster
Official: В frozen official page отдельное описание отсутствует.
$yint; обязательныйвертикальная координата от верхнего края; у текста это baseline
Official: В frozen official page отдельное описание отсутствует.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Splices a solid color into the image

Description: Splices a solid color into the image.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 556dcee9228c6fd9fdfbeadbb331dddba5c3425357e0aab0da4f1725e308b920; SHA XML: f97b3aa902238bfc043abd262577e1787be3a555a40249c9a5b8b56335de5e48.

Imagick::thumbnailImageПолучить лёгкое превью загруженной фотографии.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::thumbnailImage(int $columns, int $rows, bool $bestfit = false, bool $fill = false, bool $legacy = false): bool

Реальная потребность. Получить лёгкое превью загруженной фотографии.

Что получится. Уменьшить кадр до target box с опциями bestfit/fill.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::thumbnailImage(int $columns, int $rows, bool $bestfit = false, bool $fill = false, bool $legacy = false): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::thumbnailImage(int $columns, int $rows, bool $bestfit = false, bool $fill = false, bool $legacy = false): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: Image width
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: Image height
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to force maximum values
$fillbool; по умолчанию falseзначение точного типа из сигнатуры
Official: If the image does not fill the box completely then the box is filled with image's background color.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Round the smaller dimension down instead to the closest integer.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Fill может изменить ожидаемую геометрию, а многокадровый объект требует явного цикла. При ошибке выбрасывается ImagickException.

Граница. Метод ориентирован на thumbnail и может удалять/упрощать часть состояния.

Что выбрать рядом. Resizeimage для полного контроля качества и metadata.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: получить лёгкое превью загруженной фотографииПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->thumbnailImage(6, 4, true, false, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] <= 6 && $afterGeometry['height'] <= 4;
    $artifact = __DIR__ . '/out/' . 'thumbnailimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::thumbnailImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: уменьшить кадр до target box с опциями bestfit/fillПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->thumbnailImage(8, 5, true, true, false);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 5;
    $artifact = __DIR__ . '/out/' . 'thumbnailimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::thumbnailImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$columnsint; обязательныйцелевая ширина или ширина области в пикселях
Official: Image width
$rowsint; обязательныйцелевая высота или высота области в пикселях
Official: Image height
$bestfitbool; по умолчанию falseсохранить пропорции и вписать изображение в обе заданные стороны
Official: Whether to force maximum values
$fillbool; по умолчанию falseзначение точного типа из сигнатуры
Official: If the image does not fill the box completely then the box is filled with image's background color.
$legacybool; по умолчанию falseвоспроизвести старое округление imagick до 3.4.0; для нового кода false
Official: Round the smaller dimension down instead to the closest integer.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Changes the size of an image

Description: Changes the size of an image to the given dimensions and removes any associated profiles. The goal is to produce small, low cost thumbnail images suited for display on the Web. If true is given as a third parameter then columns and rows parameters are used as maximums for each side. Both sides will be scaled down until they match or are smaller than the parameter given for the side. With bestfit enabled the image fits inside the requested box while preserving its aspect ratio.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 6eaafc30c5cbb181b139094254b5cab252adf9466af2d46bb0d9d592c5f14d67; SHA XML: f8f204ee85d086a099c38b6859b2d5c7161d83d091cf7cc3ac97dc4076ea30be.

Imagick::transformImageОдной устаревшей convenience-операцией crop-нуть и изменить размер.

PECL imagick 2, PECL imagick 3; deprecated: PECL imagick 3.4.4 · imagick

Imagick::transformImage(string $crop, string $geometry): Imagick

Реальная потребность. Одной устаревшей convenience-операцией crop-нуть и изменить размер.

Что получится. Вернуть отдельный imagick с преобразованным кадром.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::transformImage(string $crop, string $geometry): Imagick либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::transformImage(string $crop, string $geometry): Imagick; модификаторы: public.

ПараметрТип и обязательностьКак читать
$cropstring; обязательныйgeometry string области crop
Official: A crop geometry string. This geometry defines a subregion of the image to crop.
$geometrystring; обязательныйgeometry string итогового размера
Official: An image geometry string. This geometry defines the final size of the image.

Возврат: Imagick. Возвращается новый объект Imagick. Дальше используют и освобождают именно его, не исходник.

Когда ломается. Если продолжить работу с исходным объектом, результат будто исчезает. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Метод deprecated с pecl imagick 3.4.4.

Что выбрать рядом. Явные cropimage + resetimagepage + resizeimage.

Доступность. PECL imagick 2, PECL imagick 3; deprecated: PECL imagick 3.4.4.

Минимальный контрольный пример: одной устаревшей convenience-операцией crop-нуть и изменить размерПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transformImage('6x4+1+1', '8x6');
    $checks = ['return_contract' => $result instanceof Imagick];
    $transformed = $result;
    $after = $transformed->getImageGeometry();
    $effect = ['new_object' => $transformed !== $image, 'geometry' => $after];
    $checks['new_object'] = $transformed instanceof Imagick && $transformed !== $image;
    $artifact = __DIR__ . '/out/' . 'transformimage-minimal.png';
    $transformed->setImageFormat('png');
    $transformed->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transformImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: вернуть отдельный Imagick с преобразованным кадромПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transformImage('8x5+2+2', '10x6');
    $checks = ['return_contract' => $result instanceof Imagick];
    $transformed = $result;
    $after = $transformed->getImageGeometry();
    $effect = ['new_object' => $transformed !== $image, 'geometry' => $after];
    $checks['new_object'] = $transformed instanceof Imagick && $transformed !== $image;
    $artifact = __DIR__ . '/out/' . 'transformimage-workflow.png';
    $transformed->setImageFormat('png');
    $transformed->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transformImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$cropstring; обязательныйgeometry string области crop
Official: A crop geometry string. This geometry defines a subregion of the image to crop.
$geometrystring; обязательныйgeometry string итогового размера
Official: An image geometry string. This geometry defines the final size of the image.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Convenience method for setting crop size and the image geometry

Description: A convenience method for setting crop size and the image geometry from strings. Доступность зависит от версии ImageMagick не ниже 6.2.9.

Return: Returns an Imagick object containing the transformed image.

Errors: —

Changelog: —

SHA страницы: d7ce80049adcf6298da5aa6c448936115f95e39909a819a38e53897ddf487706; SHA XML: 8367ed05a7041488a7da48e57347edef12096035feb7ffb84f6df8b537892fa8.

Связи официальной страницы. Imagick::cropImage, Imagick::resizeImage, Imagick::thumbnailImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::transformImageColorspaceРеально преобразовать значения каналов в целевое цветовое пространство.

PECL imagick 3 · imagick

Imagick::transformImageColorspace(int $colorspace): bool

Реальная потребность. Реально преобразовать значения каналов в целевое цветовое пространство.

Что получится. Изменить пиксели и colorspace текущего кадра.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::transformImageColorspace(int $colorspace): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::transformImageColorspace(int $colorspace): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$colorspaceint; обязательныйконстанта Imagick::COLORSPACE_* целевого пространства
Official: The colorspace the image should be transformed to, one of the COLORSPACE constants e.g. Imagick::COLORSPACE_CMYK.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Простое присвоение colorspace без корректного исходного профиля даёт неверные цвета. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Для управляемого cmyk/rgb conversion нужны корректные icc profiles.

Что выбрать рядом. Profileimage для profile-managed workflow; setimagecolorspace только для назначения состояния.

Доступность. PECL imagick 3.

Минимальный контрольный пример: реально преобразовать значения каналов в целевое цветовое пространствоПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transformImageColorspace(Imagick::COLORSPACE_GRAY);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $effect['before']['colorspace'] = $before['colorspace'];
    $effect['after']['colorspace'] = $image->getImageColorspace();
    $checks['colorspace_contract'] = $before['colorspace'] !== Imagick::COLORSPACE_GRAY && $image->getImageColorspace() === Imagick::COLORSPACE_GRAY;
    $artifact = __DIR__ . '/out/' . 'transformimagecolorspace-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transformImageColorspace',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: изменить пиксели и colorspace текущего кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->transformImageColorspace(Imagick::COLORSPACE_GRAY);
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $effect['before']['colorspace'] = $before['colorspace'];
    $effect['after']['colorspace'] = $image->getImageColorspace();
    $checks['colorspace_contract'] = $before['colorspace'] !== Imagick::COLORSPACE_SRGB && $image->getImageColorspace() === Imagick::COLORSPACE_SRGB;
    $artifact = __DIR__ . '/out/' . 'transformimagecolorspace-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transformImageColorspace',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$colorspaceint; обязательныйконстанта Imagick::COLORSPACE_* целевого пространства
Official: The colorspace the image should be transformed to, one of the COLORSPACE constants e.g. Imagick::COLORSPACE_CMYK.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Transforms an image to a new colorspace

Description: Transforms an image to a new colorspace.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: 9f92cc8ab52b6f835e4a2cf5facb0aed7f16349cc1dd63fc242e8574ef754896; SHA XML: d813b22f5eea743018695ef93d9ec0974f2b1e4c87107445b16831cce8509607.

Связи официальной страницы. Imagick::setColorSpace. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::transposeImageВыполнить точное отражение по диагонали без интерполяции произвольного угла.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::transposeImage(): bool

Реальная потребность. Выполнить точное отражение по диагонали без интерполяции произвольного угла.

Что получится. Транспонировать пиксели и поменять width/height местами.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::transposeImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::transposeImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Операцию легко перепутать с обычным rotate 90°. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Направление нужно проверить по несимметричным контрольным углам.

Что выбрать рядом. Rotateimage/flipimage/flopimage для более очевидной отдельной операции.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: выполнить точное отражение по диагонали без интерполяции произвольного углаПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transposeImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'transposeimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transposeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: транспонировать пиксели и поменять width/height местамиПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transposeImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'transposeimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transposeImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creates a vertical mirror image

Description: Creates a vertical mirror image by reflecting the pixels around the central x-axis while rotating them 90-degrees. Доступность зависит от версии ImageMagick не ниже 6.2.9.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: d0e8194510d3456b7211e14f59ccea9955ea46151957d57a86a32835fd619e3e; SHA XML: 2b727d002a3ffee071895a993c3368ee86da9a52a565c8e37d66f040561fe026.

Связи официальной страницы. Imagick::transverseImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::transverseImageВыполнить противоположное диагональное отражение для ориентации кадра.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::transverseImage(): bool

Реальная потребность. Выполнить противоположное диагональное отражение для ориентации кадра.

Что получится. Переставить пиксели поперёк диагонали и поменять стороны.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::transverseImage(): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::transverseImage(): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. На симметричной картинке transpose и transverse визуально не различить. Официальная страница не добавляет отдельного текста ошибок; ImagickException всё равно обрабатывается на границе I/O/операции.

Граница. Операция соответствует конкретной комбинации rotation+mirror.

Что выбрать рядом. Явные rotateimage и flip/flop, если читабельность важнее одного вызова.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: выполнить противоположное диагональное отражение для ориентации кадраПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transverseImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'transverseimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transverseImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: переставить пиксели поперёк диагонали и поменять стороныПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->transverseImage();
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 12;
    $artifact = __DIR__ . '/out/' . 'transverseimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::transverseImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
—без параметровМетод использует текущий кадр/состояние объекта.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Creates a horizontal mirror image

Description: Creates a horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees. Доступность зависит от версии ImageMagick не ниже 6.2.9.

Return: Returns true on success.

Errors: —

Changelog: —

SHA страницы: da32d3e5cbf5885ca5db0fb19dc1e5114d0aa80edf77ee7a663064f6fe71384f; SHA XML: cf5e339108cb01609877f257f62ca4058d9066034cb3513bca10353e3ac9758e.

Связи официальной страницы. Imagick::transposeImage. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Imagick::trimImageУдалить одноцветные поля вокруг скана или автоматически обрезать прозрачную рамку.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::trimImage(float $fuzz): bool

Реальная потребность. Удалить одноцветные поля вокруг скана или автоматически обрезать прозрачную рамку.

Что получится. Сжать кадр до bounding box пикселей, отличающихся от углового фона с учётом fuzz.

Самый маленький смысл вызова. Объект $image уже содержит один текущий кадр. Вызов Imagick::trimImage(float $fuzz): bool либо меняет этот кадр, либо возвращает измерение; ниже сначала показан маленький лабораторный вход, затем отдельная рабочая ситуация.

Перед примером: переменная, функция и return, объект и метод, try/catch/finally, пути и файлы, первый Imagick-файл, лимиты ресурсов.

Точная сигнатура. Imagick::trimImage(float $fuzz): bool; модификаторы: public.

ПараметрТип и обязательностьКак читать
$fuzzfloat; обязательныйдопуск различия цвета в quantum scale, не процент 0..100
Official: By default target must match a particular pixel color exactly. However, in many cases two colors may differ by a small amount. The fuzz member of image defines how much tolerance is acceptable to consider two colors as the same. This parameter represents the variation on the quantum range.

Возврат: bool. true подтверждает выполнение вызова, но файл и видимый эффект проверяются отдельно.

Когда ломается. Слишком большой fuzz съедает слабоконтрастный контент, а page offset остаётся. При ошибке выбрасывается ImagickException.

Граница. Фон берётся из угловой области и метод не понимает смысл объекта.

Что выбрать рядом. Cropimage по проверенным координатам; после trim вызвать resetimagepage.

Доступность. PECL imagick 2, PECL imagick 3.

Минимальный контрольный пример: удалить одноцветные поля вокруг скана или автоматически обрезать прозрачную рамкуПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick();
    $image->newPseudoImage(12, 8, 'gradient:#112233-#f0c674');
    $image->importImagePixels(0, 0, 1, 1, 'RGB', Imagick::PIXEL_CHAR, [255, 0, 0]);
    $image->setImageFormat('png');
    $image->clear();
    $image->newImage(14, 10, new ImagickPixel('#ffffff'));
    $marker = new ImagickDraw();
    $marker->setFillColor(new ImagickPixel('#006d77'));
    $marker->rectangle(3.0, 2.0, 10.0, 7.0);
    $image->drawImage($marker);
    $marker->clear();
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->trimImage(0.0);
    $checks = ['return_contract' => $result === true];
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'trimimage-minimal.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::trimImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Пример сам создаёт маленький несимметричный градиент, вызывает один изучаемый метод, проверяет return и печатает bounded JSON. Если операция меняет пиксели, создаётся отдельный PNG в ./out. Выполнение Imagick пока не заявляется.

Рабочая ситуация на другом входе: сжать кадр до bounding box пикселей, отличающихся от углового фона с учётом fuzzПример для указанного окружения
<?php
declare(strict_types=1);

function aenBound(mixed $value): mixed
{
    if ($value instanceof ImagickPixel) { return $value->getColor(false); }
    if ($value instanceof ImagickPixelIterator) { return ['type' => 'ImagickPixelIterator']; }
    if ($value instanceof Imagick) { return ['type' => 'Imagick', 'geometry' => $value->getImageGeometry()]; }
    if (is_array($value)) { return array_slice($value, 0, 12, true); }
    return $value;
}

$image = null; $reference = null; $draw = null; $iterator = null; $transformed = null; $textCanvas = null;
try {
    $outputDir = __DIR__ . '/out';
    if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) {
        throw new RuntimeException('Не удалось создать каталог результата');
    }
    $image = new Imagick(__DIR__ . '/fixtures/geometry.ppm');
    $image->setImageFormat('png');
    $image->clear();
    $image->newImage(14, 10, new ImagickPixel('#ffffff'));
    $marker = new ImagickDraw();
    $marker->setFillColor(new ImagickPixel('#e76f51'));
    $marker->rectangle(3.0, 2.0, 10.0, 7.0);
    $image->drawImage($marker);
    $marker->clear();
    $image->setImageFormat('png');
    $before = [
        'geometry' => $image->getImageGeometry(),
        'page' => $image->getImagePage(),
        'object_page' => $image->getPage(),
        'corner' => $image->getImagePixelColor(0, 0)->getColor(false),
        'signature' => $image->getImageSignature(),
        'colorspace' => $image->getImageColorspace(),
    ];
    $result = $image->trimImage(0.03 * Imagick::getQuantum());
    $checks = ['return_contract' => $result === true];
    $pageBeforeReset = $image->getImagePage();
    $image->resetImagePage('');
    $afterGeometry = $image->getImageGeometry();
    $afterPage = $image->getImagePage();
    $afterCorner = $image->getImagePixelColor(0, 0)->getColor(false);
    $afterSignature = $image->getImageSignature();
    $effect = ['before' => $before, 'after' => ['geometry' => $afterGeometry, 'page' => $afterPage, 'corner' => $afterCorner, 'signature' => $afterSignature]];
    $checks['non_empty_raster'] = $image->getImageWidth() > 0 && $image->getImageHeight() > 0;
    $checks['observable_change'] = $afterSignature !== $before['signature'] || $afterGeometry !== $before['geometry'];
    $effect['page_before_reset'] = $pageBeforeReset;
    $effect['page_after_reset'] = $afterPage;
    $checks['page_offset_reset'] = ($afterPage['x'] ?? null) === 0 && ($afterPage['y'] ?? null) === 0;
    $checks['geometry_contract'] = $afterGeometry['width'] === 8 && $afterGeometry['height'] === 6;
    $artifact = __DIR__ . '/out/' . 'trimimage-workflow.png';
    $image->setImageFormat('png');
    $image->writeImage($artifact);
    $effect['artifact'] = basename($artifact);
    $effect['bytes'] = filesize($artifact);
    $checks['artifact_written'] = is_file($artifact) && filesize($artifact) > 8;
    foreach ($checks as $check => $passed) {
        if (!$passed) { throw new LogicException('Не прошла проверка результата: ' . $check); }
    }
    $observation = [
        'method' => 'Imagick::trimImage',
        'input' => $before,
        'return' => aenBound($result),
        'effect' => $effect,
        'checks' => $checks,
    ];
    echo json_encode($observation, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
} catch (ImagickException $exception) {
    fwrite(STDERR, 'Imagick отказал: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} catch (Throwable $exception) {
    fwrite(STDERR, 'Проверка примера не пройдена: ' . $exception->getMessage() . PHP_EOL);
    exit(1);
} finally {
    if ($iterator instanceof ImagickPixelIterator) { $iterator->clear(); }
    if ($draw instanceof ImagickDraw) { $draw->clear(); }
    if ($reference instanceof Imagick) { $reference->clear(); }
    if ($transformed instanceof Imagick) { $transformed->clear(); }
    if ($textCanvas instanceof Imagick) { $textCanvas->clear(); }
    if ($image instanceof Imagick) { $image->clear(); }
}

Этот сценарий читает объявленный 12×8 PPM, использует другие параметры и принимает проверяемое решение по result/effect. Это самостоятельный workflow, а не копия с заменённым числом; runtime и visual pass отложены до окружения с Imagick.

ПараметрТип и обязательностьКак читать
$fuzzfloat; обязательныйдопуск различия цвета в quantum scale, не процент 0..100
Official: By default target must match a particular pixel color exactly. However, in many cases two colors may differ by a small amount. The fuzz member of image defines how much tolerance is acceptable to consider two colors as the same. This parameter represents the variation on the quantum range.
Полный frozen-контракт официальной страницы

Модификаторы: public

Purpose: Remove edges from the image

Description: Remove edges that are the background color from the image. Доступность зависит от версии ImageMagick не ниже 6.2.9.

Return: Returns true on success.

Errors: При ошибке выбрасывается ImagickException.

Changelog: —

SHA страницы: 2dc50fd2920db49fbbf807af03365c4b03d1503bc55449433b5a51930dba6062; SHA XML: e717308d8b2f0dfc74daa24401b59c5c4b76d88ff695da425c1163c2da4959b1.

Связи официальной страницы. Imagick::getQuantumDepth, Imagick::getQuantumRange, imagecropauto. Ссылки внутри geometry/pixels уже ведут к точной карточке; внешние получат маршрут при общей интеграции.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.