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

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

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

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

Глава 373 · После переменных, объектов, файлов, пикселей и alpha

Imagick: цвет рамки, бумажный Polaroid и настоящая подпись

От настройки цвета и копии ImagickPixel к реальной рамке, полным native снимкам, углам и рабочей IM7 подписи; без сокрытия ограничений binding.

Получить полезный файл с рамкой, бумажным эффектом и настоящей подписью

Нужно оформить карточку товара как бумажный снимок: выбрать цвет бумаги, добавить рамку, угол и подпись. Начнём с настоящих файлов. На первой иллюстрации исходник, обычная рамка, фактический Polaroid этой сборки и отдельный native вариант с желаемой подписью. У результатов разные размеры; показаны полные края и тени. Видимую TODO FIXME исходного метода сохраняем честно и объясняем, каким API собственный текст действительно передать.

Исходник → реальная рамка → native Polaroid с literal TODO → отдельный native companion с MUG01/NEW
Исходник → реальная рамка → native Polaroid с literal TODO → отдельный native companion с MUG01/NEW
Собственный прозрачный исходник400×320 показан на белом фоне
Собственный прозрачный исходник400×320 показан на белом фоне

Цвет настройки похож на выбранную краску: сама банка краски не создаёт рамку. getImageBorderColor читает цвет как ImagickPixel, setImageBorderColor меняет выбор. borderImage или Polaroid — отдельные исполнители, которые используют цвет при создании пикселей. Аналогия ограничена: это свойство объекта, а не физическое содержимое уже нарисованного файла.

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

$ok = $image->setImageBorderColor('#fff4dc');

Строка-аргумент задаёт цвет будущей рамки или бумаги подходящего потребителя. $ok содержит bool-статус true, не картинку. Сама строка не увеличивает изображение и не перекрашивает уже нарисованную рамку. Чтобы увидеть изменение, нужна отдельная операция: например borderImage($image->getImageBorderColor(), 12, 12) передаёт прочитанный цвет и толщины12 пикселей по горизонтали/вертикали.

Вначале нужна обычная рамка. Мы создаём рабочую clone-копию, читаем настроенный цвет и передаём его borderImage с толщинами12/12. Затем другая копия проходит Polaroid с явным локальным шрифтом20pt. __DIR__ — папка, require подключает опубликованный helper. echo печатает имена файлов; printf подставляет %d для целого; (int) показывает true/false как1/0. Сравнение === строго сравнивает значение/тип; method_exists проверяет возможность текущей сборки, throw прекращает сценарий при отсутствии нужного companion.

border_color — цвет бумаги; background_color в этом эффекте становится цветом тени. Исходная прозрачность на бумаге обрабатывается наложением OVER, поэтому она не обещана неизменной. Внешняя alpha новых PNG позволяет поставить карточку на сайт: тёмный просмотр делает её видимой. Формат сохранения PNG8/RGBA задан явно; размеры не сжимаются до исходных400×320. Собственный текст MUG01/NEW создаёт polaroidWithTextAndMethod, который действительно принимает caption; это видно в коде, а не скрыто внутри helper.

Получить настоящую рамку, Polaroid и подпись доступным native методом

Созданы самостоятельные PNG: реальная рамка, полный native Polaroid с TODO FIXME и отдельный native результат с MUG 01 / NEW. Последний получен polaroidWithTextAndMethod, а не замаскированной надписью предыдущего файла. Исходник сохранён; прозрачность нового внешнего пространства и тени показана отдельно на тёмном.

Получить настоящую рамку, Polaroid и подпись доступным native методомПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$ok=$prepared->setImageBorderColor('#fff4dc');
$paper=$prepared->getImageBorderColor();
$framed=clone $prepared;$framed->borderImage($paper,12,12);saveBorderPNG($framed,'actual-border.png');
$ordinary=clone $prepared;$ordinary->setImageBackgroundColor('#243c4d');
$ordinary->polaroidImage(borderDraw($font,20),0);saveBorderPNG($ordinary,'ordinary-todo.png');
if (!method_exists(Imagick::class,'polaroidWithTextAndMethod')) {throw new RuntimeException('This caption example requires the IM7 companion binding');}
$captioned=clone $prepared;$captioned->setImageBackgroundColor('#243c4d');
$captioned->polaroidWithTextAndMethod(borderDraw($font,20),0,'MUG 01 / NEW',Imagick::INTERPOLATE_BILINEAR);
saveBorderPNG($captioned,'captioned.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/captioned.png'),'#243c4d'),'captioned-dark.png',false);
saveBorderPNG($sourceWhite,'source-preview8.png',false);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/actual-border.png')),borderPreview(new Imagick(__DIR__.'/ordinary-todo.png')),borderPreview(new Imagick(__DIR__.'/captioned.png'))], 'polaroid-border-first.png');
saveBorderDiagnostic('polaroid-border-first', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'first','paper'=>borderColorInfo($paper),'setter_return'=>$ok,'ordinary_caption'=>'TODO FIXME (literal in this IM7 wrapper)','requested_real_caption'=>'MUG 01 / NEW','caption_method'=>'polaroidWithTextAndMethod','outputs'=>['actual-border.png'=>borderState($framed),'ordinary-todo.png'=>borderState($ordinary),'captioned.png'=>borderState($captioned)]]);
echo "polaroid-border-first.png\nactual-border.png\nordinary-todo.png\ncaptioned.png\nsource-preview8.png\ncaptioned-dark.png\nmetrics.json\n";
printf("setter=%d source-unchanged=%d actual-caption-method=1\n",(int)$ok,(int)($before===borderState($source)));

Созданы самостоятельные PNG: реальная рамка, полный native Polaroid с TODO FIXME и отдельный native результат с MUG 01 / NEW. Последний получен polaroidWithTextAndMethod, а не замаскированной надписью предыдущего файла. Исходник сохранён; прозрачность нового внешнего пространства и тени показана отдельно на тёмном. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-border-first.png
actual-border.png
ordinary-todo.png
captioned.png
source-preview8.png
captioned-dark.png
metrics.json
setter=1 source-unchanged=1 actual-caption-method=1

Отделить цвет настройки, pixel-копию и готовый растр

Свойство и рисунок живут на разных стадиях. Getter возвращает отдельную копию цвета; изменение этой копии не изменяет объект изображения. Setter меняет настройку, а не уже построенный растр. При следующей операции цвет снова передаётся потребителю. На модели используются реальные имена и цвета: cream#fff4dc, изменённый pixel#dd3355, новая blue#226b82.

Настройка объекта → копия ImagickPixel → отдельный потребитель: нарисованная рамка не перекрашивается setter
Настройка объекта → копия ImagickPixel → отдельный потребитель: нарисованная рамка не перекрашивается setter
ДействиеЧто изменилосьЧто увидит читатель
setImageBorderColor(cream)Свойство объектаТот же исходник400×320
getImageBorderColor → pixel.setColor(red)Отдельный pixel-объектНастройка изображения всё ещё cream
borderImage(cream,12,12)Реальный растрКремовая рамка424×344
setter blue после рисованияНастройка, не прежняя рамкаСтарые424×344 пиксели те же
Ещё один borderImage(blue,12,12)Новые внешние пикселиСиняя рамка снаружи прежней:448×368

Массив в metrics.json описывает фактические состояния/цвета и геометрию панелей. SHA компонентов отвечает только за точное сравнение названного RGBА8-представления, а не за все метаданные. Сам файл уже нарисованной рамки отдельно сравнивается до/после setter. Это полезно, если настройка меняется в середине обработки и разработчик ожидает перекрасить сохранённый PNG.

Отличить настройку цвета, копию getter и уже нарисованные пиксели

Изменение цвета-свойства не рисует рамку и не перекрашивает существующую. Изменение возвращённого ImagickPixel не меняет свойство изображения. Только следующая операция borderImage потребляет явно прочитанный цвет и создаёт новую синюю внешнюю рамку.

Отличить настройку цвета, копию getter и уже нарисованные пикселиПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$prepared->setImageBorderColor('#fff4dc');saveBorderPNG($prepared,'property-only.png');
$pixel=$prepared->getImageBorderColor();$stored=borderColorInfo($pixel);$pixel->setColor('#dd3355');
$fresh=$prepared->getImageBorderColor();
$framed=clone $prepared;$framed->borderImage($fresh,12,12);saveBorderPNG($framed,'cream-frame.png');$drawn=borderState($framed);
$framed->setImageBorderColor('#226b82');saveBorderPNG($framed,'metadata-only-frame.png');$afterMetadata=borderState($framed);
$framed->borderImage($framed->getImageBorderColor(),12,12);saveBorderPNG($framed,'blue-outer-frame.png');

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/property-only.png')),borderPreview(new Imagick(__DIR__.'/cream-frame.png')),borderPreview(new Imagick(__DIR__.'/blue-outer-frame.png'))], 'polaroid-border-controls.png');
saveBorderDiagnostic('polaroid-border-controls', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'controls','getter_original'=>$stored,'mutated_pixel'=>borderColorInfo($pixel),'getter_after_mutation'=>borderColorInfo($fresh),'property_only_source_exact'=>$before===borderState($prepared),'drawn_frame_unchanged_by_setter'=>$drawn===$afterMetadata,'outputs'=>['cream-frame.png'=>$drawn,'metadata-only-frame.png'=>$afterMetadata,'blue-outer-frame.png'=>borderState($framed)]]);
echo "polaroid-border-controls.png\nproperty-only.png\ncream-frame.png\nmetadata-only-frame.png\nblue-outer-frame.png\nmetrics.json\n";
printf("property-only-exact=%d getter-copy=%d existing-frame-unchanged=%d\n",(int)($before===borderState($prepared)),(int)($stored===borderColorInfo($fresh)),(int)($drawn===$afterMetadata));

Изменение цвета-свойства не рисует рамку и не перекрашивает существующую. Изменение возвращённого ImagickPixel не меняет свойство изображения. Только следующая операция borderImage потребляет явно прочитанный цвет и создаёт новую синюю внешнюю рамку. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-border-controls.png
property-only.png
cream-frame.png
metadata-only-frame.png
blue-outer-frame.png
metrics.json
property-only-exact=1 getter-copy=1 existing-frame-unchanged=1

Прочитать цвет и проверить договорённость после сохранения

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

$color = $image->getImageBorderColor();
$components = $color->getColor(1);

Пустые скобки означают отсутствие аргументов. В $color приходит объект ImagickPixel, представляющий один цвет. getColor(1) возвращает массив нормированных компонент r/g/b/a; например r=1 означает максимальный красный. Это чтение настройки текущего объекта, а не поиск цвета в видимой рамке фотографии. Возвращённый pixel — отдельная копия: его setColor не переписывает свойство изображения.

Настоящий цветовой swatch и рамка; после PNG-чтения рисунок тот же, настройка может стать серой
Настоящий цветовой swatch и рамка; после PNG-чтения рисунок тот же, настройка может стать серой

Прочитать цвет как объект и передать его рисующей операции

Getter возвращает ImagickPixel с кремовым RGB255,244,220, а не true и не снимок рамочных пикселей. Его можно разобрать на компоненты, показать реальным swatch и передать borderImage. Последняя операция действительно увеличивает растр с400×320 до424×344.

Прочитать цвет как объект и передать его рисующей операцииПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$prepared->setImageBorderColor('#fff4dc');
$color=$prepared->getImageBorderColor();$values=$color->getColor(1);
$swatch=new Imagick();$swatch->newImage(80,80,$color);saveBorderPNG($swatch,'color-swatch.png',false);
$frame=clone $source;$frame->borderImage($color,12,12);saveBorderPNG($frame,'getter-frame.png');

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/getter-frame.png'))], 'border-get-minimal.png');
saveBorderDiagnostic('polaroid-border-getimagebordercolor-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'get-minimal','color'=>borderColorInfo($color),'return_type'=>get_debug_type($color),'outputs'=>['getter-frame.png'=>borderState($frame)],'corner'=>$frame->getImagePixelColor(0,0)->getColor(1)]);
echo "border-get-minimal.png\ncolor-swatch.png\ngetter-frame.png\nmetrics.json\n";
printf("class=%s RGB=%d,%d,%d\n",get_debug_type($color),(int)round($values['r']*255),(int)round($values['g']*255),(int)round($values['b']*255));

Getter возвращает ImagickPixel с кремовым RGB255,244,220, а не true и не снимок рамочных пикселей. Его можно разобрать на компоненты, показать реальным swatch и передать borderImage. Последняя операция действительно увеличивает растр с400×320 до424×344. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-get-minimal.png
color-swatch.png
getter-frame.png
metrics.json
class=ImagickPixel RGB=255,244,220

Более практичная задача: один скрипт сохраняет исходник, другой позже оформляет его под стиль сайта. Нельзя считать сохранённый PNG переносчиком каждой настройки объекта Imagick. В нашем повторном чтении border_color становится223,223,223, хотя RGBA исходника сохранился. Сначала смотрим фактическую настройку getter, затем явно восстанавливаем политику проекта. Если нужно передавать её между запросами/процессами, храните цвет в конфигурации приложения, а не угадывайте его по файлу.

Проверить настройку после PNG-чтения и восстановить политику проекта

В этой PNG-цепочке пиксели сохранились точно, а настройка border_color после чтения вернулась к серому223,223,223. Getter помогает обнаружить различие объекта и файла. Явно восстановленная политика даёт ту же синюю рамку, что была до сохранения; файл не используется как обещанное хранилище настройки.

Проверить настройку после PNG-чтения и восстановить политику проектаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$prepared->setImageBorderColor('#226b82');$policyColor=$prepared->getImageBorderColor();
saveBorderPNG($prepared,'property-snapshot.png');$reload=new Imagick(__DIR__.'/property-snapshot.png');$reloadedColor=$reload->getImageBorderColor();
$beforeFrame=clone $prepared;$beforeFrame->borderImage($policyColor,12,12);saveBorderPNG($beforeFrame,'before-save-frame.png');
$defaultFrame=clone $reload;$defaultFrame->borderImage($reloadedColor,12,12);saveBorderPNG($defaultFrame,'reloaded-default-frame.png');
$reload->setImageBorderColor($policyColor);$restoredColor=$reload->getImageBorderColor();
$restored=clone $reload;$restored->borderImage($restoredColor,12,12);saveBorderPNG($restored,'restored-policy-frame.png');

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/before-save-frame.png')),borderPreview(new Imagick(__DIR__.'/reloaded-default-frame.png')),borderPreview(new Imagick(__DIR__.'/restored-policy-frame.png'))], 'border-get-reload.png');
saveBorderDiagnostic('polaroid-border-getimagebordercolor-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'get-workflow','before_color'=>borderColorInfo($policyColor),'reloaded_color'=>borderColorInfo($reloadedColor),'restored_color'=>borderColorInfo($restoredColor),'snapshot_RGBA_exact'=>$before['RGBA8_hash']===borderState(new Imagick(__DIR__.'/property-snapshot.png'))['RGBA8_hash'],'restored_frame_RGBA_exact'=>borderPixelHash($beforeFrame)===borderPixelHash($restored),'outputs'=>['before-save-frame.png'=>borderState($beforeFrame),'reloaded-default-frame.png'=>borderState($defaultFrame),'restored-policy-frame.png'=>borderState($restored)]]);
echo "border-get-reload.png\nproperty-snapshot.png\nbefore-save-frame.png\nreloaded-default-frame.png\nrestored-policy-frame.png\nmetrics.json\n";
printf("saved-pixels-exact=%d restored-frame-exact=%d\n",(int)($before['RGBA8_hash']===borderState(new Imagick(__DIR__.'/property-snapshot.png'))['RGBA8_hash']),(int)(borderPixelHash($beforeFrame)===borderPixelHash($restored)));

В этой PNG-цепочке пиксели сохранились точно, а настройка border_color после чтения вернулась к серому223,223,223. Getter помогает обнаружить различие объекта и файла. Явно восстановленная политика даёт ту же синюю рамку, что была до сохранения; файл не используется как обещанное хранилище настройки. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-get-reload.png
property-snapshot.png
before-save-frame.png
reloaded-default-frame.png
restored-policy-frame.png
metrics.json
saved-pixels-exact=1 restored-frame-exact=1

Выбрать цвет и использовать его в реальном оформлении

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

$ok = $image->setImageBorderColor('#fff4dc');

Строка-аргумент задаёт цвет будущей рамки или бумаги подходящего потребителя. $ok содержит bool-статус true, не картинку. Сама строка не увеличивает изображение и не перекрашивает уже нарисованную рамку. Чтобы увидеть изменение, нужна отдельная операция: например borderImage($image->getImageBorderColor(), 12, 12) передаёт прочитанный цвет и толщины12 пикселей по горизонтали/вертикали.

Setter без рисования, настоящий border consumer и два native цвета бумаги с отдельной тенью
Setter без рисования, настоящий border consumer и два native цвета бумаги с отдельной тенью

Задать цвет строкой и увидеть отдельный момент рисования

Setter вернул bool true и сохранил цвет для текущего изображения. До borderImage исходные пиксели и размер не изменились. После отдельного потребителя появился реальный синий бордюр12px по каждой стороне; итог424×344 и тёмный просмотр сохранены.

Задать цвет строкой и увидеть отдельный момент рисованияПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$ok=$prepared->setImageBorderColor('#226b82');$after=borderState($prepared);
saveBorderPNG($prepared,'set-property-only.png');
$prepared->borderImage($prepared->getImageBorderColor(),12,12);saveBorderPNG($prepared,'set-actual-border.png');
saveBorderPNG(borderPreview(new Imagick(__DIR__.'/set-actual-border.png'),'#243c4d'),'set-border-dark.png',false);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/set-property-only.png')),borderPreview(new Imagick(__DIR__.'/set-actual-border.png'))], 'border-set-minimal.png');
saveBorderDiagnostic('polaroid-border-setimagebordercolor-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'set-minimal','return_type'=>get_debug_type($ok),'return_value'=>$ok,'property_only_state'=>$after,'property_only_source_exact'=>$before===$after,'color'=>borderColorInfo($prepared->getImageBorderColor()),'outputs'=>['set-actual-border.png'=>borderState($prepared)]]);
echo "border-set-minimal.png\nset-property-only.png\nset-actual-border.png\nset-border-dark.png\nmetrics.json\n";
printf("ok=%d property-only-exact=%d final=%dx%d\n",(int)$ok,(int)($before===$after),$prepared->getImageWidth(),$prepared->getImageHeight());

Setter вернул bool true и сохранил цвет для текущего изображения. До borderImage исходные пиксели и размер не изменились. После отдельного потребителя появился реальный синий бордюр12px по каждой стороне; итог424×344 и тёмный просмотр сохранены. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-set-minimal.png
set-property-only.png
set-actual-border.png
set-border-dark.png
metrics.json
ok=1 property-only-exact=1 final=424x344

Когда появляются несколько стилей карточек, создайте понятный список пресетов. foreach перебирает пары имя→цвет массива, new ImagickPixel создаёт объект одного цвета. Для каждого пресета clone сохраняет исходник. Setter принимает строку и pixel; Polaroid затем действительно использует цвет для бумаги. Не называем полароидную подпись пользовательской: оба обычных native результата этой сборки сохраняют TODO FIXME.

Использовать строку и ImagickPixel в двух бумажных пресетах

Два пресета показывают поддерживаемые формы входа: строка и ImagickPixel. Native Polaroid действительно использует border_color для бумаги. Цвет тени задан отдельно через background_color. Обе карточки честно сохраняют видимую TODO FIXME этой обёртки; настройка бумаги не решает ограничение подписи.

Использовать строку и ImagickPixel в двух бумажных пресетахПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$presets=['cream'=>'#fff4dc','blue'=>new ImagickPixel('#226b82')];$outputs=[];$returns=[];$colors=[];
foreach($presets as $name=>$color){
    $card=clone $source;$returns[$name]=$card->setImageBorderColor($color);$colors[$name]=borderColorInfo($card->getImageBorderColor());
    $card->setImageBackgroundColor('#243c4d');$card->polaroidImage(borderDraw($font,20),0);
    saveBorderPNG($card,$name.'-paper.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/'.$name.'-paper.png'),'#243c4d'),$name.'-paper-dark.png',false);$outputs[$name.'-paper.png']=borderState($card);
}

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/cream-paper.png')),borderPreview(new Imagick(__DIR__.'/blue-paper.png'))], 'border-set-presets.png');
saveBorderDiagnostic('polaroid-border-setimagebordercolor-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'set-workflow','returns'=>$returns,'colors'=>$colors,'outputs'=>$outputs,'caption_limit'=>'Both actual polaroidImage outputs retain visible TODO FIXME in this IM7 wrapper']);
echo "border-set-presets.png\ncream-paper.png\ncream-paper-dark.png\nblue-paper.png\nblue-paper-dark.png\nmetrics.json\n";
printf("presets=2 string-ok=%d pixel-ok=%d source-unchanged=%d\n",(int)$returns['cream'],(int)$returns['blue'],(int)($before===borderState($source)));

Два пресета показывают поддерживаемые формы входа: строка и ImagickPixel. Native Polaroid действительно использует border_color для бумаги. Цвет тени задан отдельно через background_color. Обе карточки честно сохраняют видимую TODO FIXME этой обёртки; настройка бумаги не решает ограничение подписи. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-set-presets.png
cream-paper.png
cream-paper-dark.png
blue-paper.png
blue-paper-dark.png
metrics.json
presets=2 string-ok=1 pixel-ok=1 source-unchanged=1

Создать эффект, выбрать угол и корректно передать подпись

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

$settings = new ImagickDraw();
$settings->setFont(__DIR__ . '/font.ttf');
$settings->setFontSize(20);
$settings->setFillColor('#173c49');
$ok = $image->polaroidImage($settings, 0);

ImagickDraw хранит параметры рисования, а не изображение. Здесь20 — размер шрифта в points, не толщина рамки; локальный font.ttf задаёт воспроизводимый шрифт. __DIR__ — папка программы, . соединяет строки пути. Угол0 не отключает эффект. Метод меняет $image; если нужен исходник, сначала $image = clone $source. Полная программа сохраняет PNG с новой геометрией и показывает всю тень.

Полные native результаты углов−12,0,+12: геометрия меняется, тень не обрезана
Полные native результаты углов−12,0,+12: геометрия меняется, тень не обрезана

Создать настоящий Polaroid даже при угле0

Угол0 не делает операцию нейтральной: native эффект добавил бумагу, изгиб, тень, буквальную подпись и изменил размер до448×388. Метод изменяет рабочую clone-копию и возвращает bool. Внешняя alpha результата создана эффектом; это не прежняя alpha исходного предмета.

Создать настоящий Polaroid даже при угле0Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$card=clone $source;$card->setImageBorderColor('#fff4dc');$card->setImageBackgroundColor('#243c4d');
$settings=borderDraw($font,20);$ok=$card->polaroidImage($settings,0);
saveBorderPNG($card,'polaroid-zero.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/polaroid-zero.png'),'#243c4d'),'polaroid-zero-dark.png',false);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/polaroid-zero.png'))], 'polaroid-minimal.png');
saveBorderDiagnostic('polaroid-border-polaroidimage-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'polaroid-minimal','return_type'=>get_debug_type($ok),'return_value'=>$ok,'angle'=>0.0,'paper'=>'#fff4dc','shadow'=>'#243c4d','caption'=>'TODO FIXME (literal IM7 wrapper)','outputs'=>['polaroid-zero.png'=>borderState($card)]]);
echo "polaroid-minimal.png\npolaroid-zero.png\npolaroid-zero-dark.png\nmetrics.json\n";
printf("ok=%d size=%dx%d source-unchanged=%d\n",(int)$ok,$card->getImageWidth(),$card->getImageHeight(),(int)($before===borderState($source)));

Угол0 не делает операцию нейтральной: native эффект добавил бумагу, изгиб, тень, буквальную подпись и изменил размер до448×388. Метод изменяет рабочую clone-копию и возвращает bool. Внешняя alpha результата создана эффектом; это не прежняя alpha исходного предмета. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-minimal.png
polaroid-zero.png
polaroid-zero-dark.png
metrics.json
ok=1 size=448x388 source-unchanged=1

После нулевого угла выберите компоновку на своей странице. Здесь−12/+12 — заранее заданные варианты, не случайность. Оба выросли до518×472; нулевой448×388. Virtual page описывает дополнительную геометрию/смещение, а не видимые размеры PNG. Если позже собираете общий холст, учитывайте page offset и полные границы. В этой главе сохраняем отдельные полные изображения, ничего не обрезаем и не обещаем тождество размеров на другом шрифте/исходнике/версии.

Literal TODO у polaroidImage и реальная желаемая подпись у доступного polaroidWithTextAndMethod
Literal TODO у polaroidImage и реальная желаемая подпись у доступного polaroidWithTextAndMethod

Рецепт подписи должен соответствовать PHP binding. CLI-option -caption не становится автоматически параметром polaroidImage. В Imagick 3.8.1/IM7 вызов с двумя аргументами передаёт literal TODO FIXME. Смена caption property не меняет изображение. Поэтому после проверки method_exists отдельный companion получает явные текст и interpolation. Для другой сборки можно построить бумажный холст, наложить фотографию, вызвать annotateImage и повернуть его; это другая явно обозначенная компоновка, не доказательство работы отсутствующего параметра у старого метода.

Выбрать угол и отдельно передать желаемую native подпись

Полные PNG углов−12/0/+12 позволяют выбрать компоновку, сохранив все тени. Размер±12 здесь518×472, его нельзя обрезать под исходные400×320. Для собственного текста вызывается доступный IM7 companion с явными caption/interpolation; это другой метод, не обещание, что property caption заработал у polaroidImage.

Выбрать угол и отдельно передать желаемую native подписьПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$outputs=[];
foreach(['minus12'=>-12.0,'zero'=>0.0,'plus12'=>12.0] as $name=>$angle){
    $card=clone $source;$card->setImageBorderColor('#fff4dc');$card->setImageBackgroundColor('#243c4d');
    $card->polaroidImage(borderDraw($font,20),$angle);saveBorderPNG($card,'angle-'.$name.'.png');$outputs['angle-'.$name.'.png']=borderState($card);
}
$ordinary=new Imagick(__DIR__.'/angle-zero.png');saveBorderPNG(borderPreview($ordinary,'#243c4d'),'angle-zero-dark.png',false);
if(!method_exists(Imagick::class,'polaroidWithTextAndMethod')){throw new RuntimeException('Explicit native caption companion not available');}
$captioned=clone $source;$captioned->setImageBorderColor('#fff4dc');$captioned->setImageBackgroundColor('#243c4d');
$captioned->polaroidWithTextAndMethod(borderDraw($font,20),0,'MUG 01 / NEW',Imagick::INTERPOLATE_BILINEAR);
saveBorderPNG($captioned,'actual-caption.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/actual-caption.png'),'#243c4d'),'actual-caption-dark.png',false);$outputs['actual-caption.png']=borderState($captioned);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/angle-minus12.png')),borderPreview(new Imagick(__DIR__.'/angle-plus12.png')),borderPreview(new Imagick(__DIR__.'/actual-caption.png'))], 'polaroid-angle-caption.png');
saveBorderDiagnostic('polaroid-border-polaroidimage-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'polaroid-workflow','angles'=>['minus12'=>-12.0,'zero'=>0.0,'plus12'=>12.0],'ordinary_caption'=>'TODO FIXME','actual_caption'=>'MUG 01 / NEW','caption_method'=>'polaroidWithTextAndMethod','interpolation'=>Imagick::INTERPOLATE_BILINEAR,'outputs'=>$outputs]);
echo "polaroid-angle-caption.png\nangle-minus12.png\nangle-zero.png\nangle-plus12.png\nangle-zero-dark.png\nactual-caption.png\nactual-caption-dark.png\nmetrics.json\n";
printf("angles=3 caption-method=polaroidWithTextAndMethod source-unchanged=%d\n",(int)($before===borderState($source)));

Полные PNG углов−12/0/+12 позволяют выбрать компоновку, сохранив все тени. Размер±12 здесь518×472, его нельзя обрезать под исходные400×320. Для собственного текста вызывается доступный IM7 companion с явными caption/interpolation; это другой метод, не обещание, что property caption заработал у polaroidImage. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-angle-caption.png
angle-minus12.png
angle-zero.png
angle-plus12.png
angle-zero-dark.png
actual-caption.png
actual-caption-dark.png
metrics.json
angles=3 caption-method=polaroidWithTextAndMethod source-unchanged=1

Разбирать зависимости, ошибки, alpha и полную геометрию результата

При ошибке сначала найдите стадию: подготовка шрифта, настройка цвета, выполнение эффекта, запись или повторное чтение. Все архивы включают собственный вход и фиксированный TTF с лицензией. Абсолютный путь к системному шрифту и надежда на Helvetica не нужны. borderDraw задаёт только font/font size/fill; новые методы вызываются явно в программах.

Наблюдение реального запускаЧто оно означаетСледующее действие
Пустой getter/setter/Polaroid → ImagickExceptionРастр ещё не создан/не прочитанПолучить корректный объект до операции
Неверный цвет → Unrecognized color stringЦветовая строка не распознанаИспользовать контролируемые presets или проверять ошибку
Нет font.ttf → ImagickDraw::setFont exceptionПодготовка Draw остановилась раньше PolaroidВосстановить комплект шрифта; не приписывать ошибку эффекту
Поле caption сохранилось, рисунок не изменилсяМетаданные не равны аргументу C captionИспользовать доступный native companion
PNG-чтение вернуло серый border_colorНастройка не перенеслась как ожидалосьВосстановить явную политику проекта
Угол0 дал бумагу/изгиб/теньНоль относится к финальному углу, не всему эффектуСравнить полные новые размеры/alpha

Размер20 относится к Draw point size;12 в borderImage — толщина пикселей;−12 в Polaroid — градусы. Ширина/высота готового файла отличаются от исходных и от virtual page. Результат эффекта имеет свою внешнюю прозрачность; внутренний источник уже наложен на бумагу. Чёрные поля вокруг поворота нельзя исправлять случайным включением alpha: выясните, где создан фон и какой формат сохраняете. Сравните настоящие PNG на белом/тёмном фоне и настройки конкретной версии, не смешивайте CLI и PHP API.

Полный helper, включённый в каждый архив

<?php
declare(strict_types=1);
function restoreBorderInputs(): void {
    foreach (['source.png'=>'f51e5780445e0f5130a7f23112b2a00618035afd5545b8e3042c7ccff09b617c','font.ttf'=>'13c03e22a633919beb2847c58c8285fb8a735ee97097d7c48fd403f8294b05f8'] as $name=>$hash) {
        $text=file_get_contents(__DIR__.'/'.$name.'.b64');
        $bytes=$text===false?false:base64_decode($text,true);
        if ($bytes===false || hash('sha256',$bytes)!==$hash || file_put_contents(__DIR__.'/'.$name,$bytes)===false) { throw new RuntimeException('Own input missing or changed: '.$name); }
    }
}
function borderPixelHash(Imagick $image, string $channels='RGBA'): string {
    return hash('sha256',json_encode($image->exportImagePixels(0,0,$image->getImageWidth(),$image->getImageHeight(),$channels,Imagick::PIXEL_CHAR),JSON_THROW_ON_ERROR));
}
function borderState(Imagick $image): array {
    return ['width'=>$image->getImageWidth(),'height'=>$image->getImageHeight(),'alpha'=>$image->getImageAlphaChannel(),'RGBA8_hash'=>borderPixelHash($image),'alpha8_hash'=>borderPixelHash($image,'A'),'page'=>$image->getImagePage()];
}
function borderColorInfo(ImagickPixel $pixel): array {
    return ['class'=>get_debug_type($pixel),'normalized_RGBA'=>$pixel->getColor(1),'string'=>$pixel->getColorAsString()];
}
function borderDraw(string $font, float $size=20): ImagickDraw {
    $draw=new ImagickDraw();$draw->setFont($font);$draw->setFontSize($size);$draw->setFillColor('#173c49');return $draw;
}
function borderPreview(Imagick $image, string $background='white'): Imagick {
    $view=new Imagick();$view->newImage($image->getImageWidth(),$image->getImageHeight(),$background);
    $view->compositeImage($image,Imagick::COMPOSITE_OVER,0,0);$view->setImageType(Imagick::IMGTYPE_TRUECOLOR);return $view;
}
function saveBorderPNG(Imagick $image, string $name, bool $alpha=true): void {
    $copy=clone $image;$copy->setImageFormat('png');$copy->setImageDepth(8);$copy->setOption('png:bit-depth','8');$copy->setOption('png:color-type',$alpha?'6':'2');
    if (!$copy->writeImage(__DIR__.'/'.$name)) {throw new RuntimeException('PNG write failed');}
}
function saveBorderComparison(array $panels, string $name): array {
    $width=array_sum(array_map(fn($im)=>$im->getImageWidth(),$panels));$height=max(array_map(fn($im)=>$im->getImageHeight(),$panels));
    $board=new Imagick();$board->newImage($width,$height,'white');$x=0;$rects=[];
    foreach($panels as $im){$y=intdiv($height-$im->getImageHeight(),2);$board->compositeImage($im,Imagick::COMPOSITE_OVER,$x,$y);$rects[]=['x'=>$x,'y'=>$y,'width'=>$im->getImageWidth(),'height'=>$im->getImageHeight()];$x+=$im->getImageWidth();}
    saveBorderPNG($board,$name,false);return $rects;
}
function saveBorderDiagnostic(string $id,array $data): void {
    $doc=['schema'=>'aen-polaroid-border-program-diagnostics-v1','example_id'=>$id]+$data;
    if(file_put_contents(__DIR__.'/metrics.json',json_encode($doc,JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION|JSON_THROW_ON_ERROR)."\n")===false){throw new RuntimeException('Diagnostic write failed');}
}

restoreBorderInputs проверяет source/font SHA и восстанавливает файлы. borderPreview создаёт свежий фон и накладывает весь растр OVER; этот фон существует только в представлении для просмотра. saveBorderPNG задаёт PNG8 и RGB/RGBA явно. saveBorderComparison размещает полные изображения без масштабирования, выравнивая их по центру общей высоты, и возвращает точные прямоугольники. borderState и metrics.json сохраняют фактические размеры/page/контрольные значения. Helper не подменяет три изучаемых метода или companion.

Применить оформление в своём приложении без смешивания стадий

Выбрать действие: читать/менять цвет, нарисовать рамку, создать native снимок или передать явную подпись
Выбрать действие: читать/менять цвет, нарисовать рамку, создать native снимок или передать явную подпись
Нужный результатИнструментЧто проверить
Узнать настройку цветаgetImageBorderColorЭто ImagickPixel-копия, не поиск цвета готовой рамки
Выбрать цвет будущей бумагиsetImageBorderColorСам по себе не меняет пиксели
Добавить обычный бордюрЯвный borderImage с прочитанным цветомТолщины вpx, новые размеры и alpha
Получить бумагу/изгиб/тень/уголpolaroidImageШрифт, текущий binding, literal caption и полные границы
Нужна собственная native подпись в этой сборкеpolaroidWithTextAndMethod после method_existsЯвные text/interpolation и проверенная доступность метода

Упражнение: заменить кремовый preset на свой цвет, оставить исходник и получить два угла. Сначала измените массив presets, затем вызов эффекта на каждой clone-копии; запишите отдельные PNG, посмотрите фактические размеры и весь силуэт на двух фонах. Не считайте обновление setter перекраской сохранённого файла. Для общего фотостека следующим шагом станет отдельный холст и продуманное размещение; это новая задача, а не скрытая часть этих восьми примеров.

CLI-код печатает диагностический текст и сохраняет изображения. Для сайта отдельный обработчик после подготовки файла выбирает настоящий Content-Type и отправляет только бинарное содержимое, без предшествующего echo. Связанные темы: файлы, HTTP-ответ, фон и alpha, типы пикселей/PNG, формат и качество. Числа геометрии и поведение подписи здесь привязаны к установленным PHP 8.5.11, Imagick 3.8.1 и ImageMagick 7.1.1-46; нет общего обещания скорости или одинаковых метаданных всех форматов.

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

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

Imagick::getImageBorderColorВозвращает новый объект ImagickPixel с копией цвета; аргументов нет.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::getImageBorderColor(): ImagickPixel

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

Прочитать цвет-свойство текущего изображения: настоящие сохранённые изображения и явные границы операции
Прочитать цвет-свойство текущего изображения: настоящие сохранённые изображения и явные границы операции
$color = $image->getImageBorderColor();
$components = $color->getColor(1);

Пустые скобки означают отсутствие аргументов. В $color приходит объект ImagickPixel, представляющий один цвет. getColor(1) возвращает массив нормированных компонент r/g/b/a; например r=1 означает максимальный красный. Это чтение настройки текущего объекта, а не поиск цвета в видимой рамке фотографии. Возвращённый pixel — отдельная копия: его setColor не переписывает свойство изображения.

Полный базовый контракт

Прочитать цвет-свойство текущего изображения

Imagick::getImageBorderColor(): ImagickPixel

Параметров нет.

Возвращает новый объект ImagickPixel с копией цвета; аргументов нет.

Доступность по официальному справочнику: PECL imagick 2, PECL imagick 3. Операция относится к текущему изображению объекта; для списка кадров выбирайте их и обрабатывайте осознанно.

В официальном XML правильная сигнатура возвращает ImagickPixel, но returnvalues содержит шаблон «Returns true on success». Stub, PHP C-обёртка и реальный вызов Imagick 3.8.1 подтверждают ImagickPixel. Мы показываем корректный объектный возврат, сохраняя полную исходную запись ниже. Getter создаёт новый PixelWand, копируя border_color; это не живая ссылка на настройку и не ссылка на пиксели готовой рамки. После сохранения/чтения PNG настройка может иметь другое значение при тех же пикселях.

Ошибки должны обрабатываться на соответствующей стадии. Для пустых объектов getter, setter и polaroidImage реальный запуск выбросил ImagickException. Нераспознанная строка цвета дала ImagickException с Unrecognized color string. Проверка отсутствующего font.ttf завершилась в ImagickDraw::setFont до вызова Polaroid: это ошибка подготовки Draw, нельзя приписывать её выполнению эффекта. Неверный PHP-тип аргумента также проверяет PHP. Чтение пути, наличие coder/FreeType и право записи — отдельные зависимости.

На официальной странице нет собственного примера кода. Ниже добавлены два самостоятельных применения с входом, ожидаемым выводом и настоящим изображением.

Полный исходный XML с описанием, параметрами, возвратом, ошибками и историей
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.getimagebordercolor">
 <refnamediv>
  <refname>Imagick::getImageBorderColor</refname>
  <refpurpose>Returns the image border color</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>ImagickPixel</type><methodname>Imagick::getImageBorderColor</methodname>
   <void/>
  </methodsynopsis>
  <para>
   Returns the image border color.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  &no.function.parameters;
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Прочитать цвет как объект и передать его рисующей операции

Getter возвращает ImagickPixel с кремовым RGB255,244,220, а не true и не снимок рамочных пикселей. Его можно разобрать на компоненты, показать реальным swatch и передать borderImage. Последняя операция действительно увеличивает растр с400×320 до424×344.

Прочитать цвет как объект и передать его рисующей операцииПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$prepared->setImageBorderColor('#fff4dc');
$color=$prepared->getImageBorderColor();$values=$color->getColor(1);
$swatch=new Imagick();$swatch->newImage(80,80,$color);saveBorderPNG($swatch,'color-swatch.png',false);
$frame=clone $source;$frame->borderImage($color,12,12);saveBorderPNG($frame,'getter-frame.png');

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/getter-frame.png'))], 'border-get-minimal.png');
saveBorderDiagnostic('polaroid-border-getimagebordercolor-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'get-minimal','color'=>borderColorInfo($color),'return_type'=>get_debug_type($color),'outputs'=>['getter-frame.png'=>borderState($frame)],'corner'=>$frame->getImagePixelColor(0,0)->getColor(1)]);
echo "border-get-minimal.png\ncolor-swatch.png\ngetter-frame.png\nmetrics.json\n";
printf("class=%s RGB=%d,%d,%d\n",get_debug_type($color),(int)round($values['r']*255),(int)round($values['g']*255),(int)round($values['b']*255));

Getter возвращает ImagickPixel с кремовым RGB255,244,220, а не true и не снимок рамочных пикселей. Его можно разобрать на компоненты, показать реальным swatch и передать borderImage. Последняя операция действительно увеличивает растр с400×320 до424×344. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-get-minimal.png
color-swatch.png
getter-frame.png
metrics.json
class=ImagickPixel RGB=255,244,220

Проверить настройку после PNG-чтения и восстановить политику проекта

В этой PNG-цепочке пиксели сохранились точно, а настройка border_color после чтения вернулась к серому223,223,223. Getter помогает обнаружить различие объекта и файла. Явно восстановленная политика даёт ту же синюю рамку, что была до сохранения; файл не используется как обещанное хранилище настройки.

Проверить настройку после PNG-чтения и восстановить политику проектаПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$prepared->setImageBorderColor('#226b82');$policyColor=$prepared->getImageBorderColor();
saveBorderPNG($prepared,'property-snapshot.png');$reload=new Imagick(__DIR__.'/property-snapshot.png');$reloadedColor=$reload->getImageBorderColor();
$beforeFrame=clone $prepared;$beforeFrame->borderImage($policyColor,12,12);saveBorderPNG($beforeFrame,'before-save-frame.png');
$defaultFrame=clone $reload;$defaultFrame->borderImage($reloadedColor,12,12);saveBorderPNG($defaultFrame,'reloaded-default-frame.png');
$reload->setImageBorderColor($policyColor);$restoredColor=$reload->getImageBorderColor();
$restored=clone $reload;$restored->borderImage($restoredColor,12,12);saveBorderPNG($restored,'restored-policy-frame.png');

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/before-save-frame.png')),borderPreview(new Imagick(__DIR__.'/reloaded-default-frame.png')),borderPreview(new Imagick(__DIR__.'/restored-policy-frame.png'))], 'border-get-reload.png');
saveBorderDiagnostic('polaroid-border-getimagebordercolor-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'get-workflow','before_color'=>borderColorInfo($policyColor),'reloaded_color'=>borderColorInfo($reloadedColor),'restored_color'=>borderColorInfo($restoredColor),'snapshot_RGBA_exact'=>$before['RGBA8_hash']===borderState(new Imagick(__DIR__.'/property-snapshot.png'))['RGBA8_hash'],'restored_frame_RGBA_exact'=>borderPixelHash($beforeFrame)===borderPixelHash($restored),'outputs'=>['before-save-frame.png'=>borderState($beforeFrame),'reloaded-default-frame.png'=>borderState($defaultFrame),'restored-policy-frame.png'=>borderState($restored)]]);
echo "border-get-reload.png\nproperty-snapshot.png\nbefore-save-frame.png\nreloaded-default-frame.png\nrestored-policy-frame.png\nmetrics.json\n";
printf("saved-pixels-exact=%d restored-frame-exact=%d\n",(int)($before['RGBA8_hash']===borderState(new Imagick(__DIR__.'/property-snapshot.png'))['RGBA8_hash']),(int)(borderPixelHash($beforeFrame)===borderPixelHash($restored)));

В этой PNG-цепочке пиксели сохранились точно, а настройка border_color после чтения вернулась к серому223,223,223. Getter помогает обнаружить различие объекта и файла. Явно восстановленная политика даёт ту же синюю рамку, что была до сохранения; файл не используется как обещанное хранилище настройки. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-get-reload.png
property-snapshot.png
before-save-frame.png
reloaded-default-frame.png
restored-policy-frame.png
metrics.json
saved-pixels-exact=1 restored-frame-exact=1
Imagick::setImageBorderColorВозвращает true при успехе; меняет настройку объекта, а не готовые пиксели.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::setImageBorderColor(ImagickPixel|string $border_color): bool

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

Задать цвет-свойство, которое использует следующая подходящая операция: настоящие сохранённые изображения и явные границы операции
Задать цвет-свойство, которое использует следующая подходящая операция: настоящие сохранённые изображения и явные границы операции
$ok = $image->setImageBorderColor('#fff4dc');

Строка-аргумент задаёт цвет будущей рамки или бумаги подходящего потребителя. $ok содержит bool-статус true, не картинку. Сама строка не увеличивает изображение и не перекрашивает уже нарисованную рамку. Чтобы увидеть изменение, нужна отдельная операция: например borderImage($image->getImageBorderColor(), 12, 12) передаёт прочитанный цвет и толщины12 пикселей по горизонтали/вертикали.

Полный базовый контракт

Задать цвет-свойство, которое использует следующая подходящая операция

Imagick::setImageBorderColor(ImagickPixel|string $border_color): bool
ПараметрЧто он означает
$border: mixed в XML; ImagickPixel|string в Imagick 3.8.1Обязательный цвет: строка, например #fff4dc, либо объект ImagickPixel. Это настройка текущего изображения, не команда рисования.

Возвращает true при успехе; меняет настройку объекта, а не готовые пиксели.

Доступность по официальному справочнику: PECL imagick 2, PECL imagick 3. Операция относится к текущему изображению объекта; для списка кадров выбирайте их и обрабатывайте осознанно.

В исходном XML параметр называется border и имеет исторический тип mixed. В stub и Reflection проверенной Imagick 3.8.1 его имя border_color, допустимый PHP-тип ImagickPixel|string. Примеры передают аргумент позиционно. С PECL imagick 2.1.0 разрешена строка с цветом; прежние версии принимали только ImagickPixel. Оба варианта показаны рабочим сценарием. Исходная сигнатура и changelog сохранены полностью:

Imagick::setImageBorderColor(mixed $border): bool

Setter копирует цвет в свойство текущего изображения. Он не добавляет толщину, не делает прозрачность и не перекрашивает уже нарисованные края. Конкретный потребитель определяет смысл: borderImage использует цвет для рамки, native Polaroid — для бумаги и фона подписи. Не путайте с background_color, который этот Polaroid-потребитель использует при создании тени. Файл PNG с тем же рисунком не обязан переносить объектную настройку border_color.

Ошибки должны обрабатываться на соответствующей стадии. Для пустых объектов getter, setter и polaroidImage реальный запуск выбросил ImagickException. Нераспознанная строка цвета дала ImagickException с Unrecognized color string. Проверка отсутствующего font.ttf завершилась в ImagickDraw::setFont до вызова Polaroid: это ошибка подготовки Draw, нельзя приписывать её выполнению эффекта. Неверный PHP-тип аргумента также проверяет PHP. Чтение пути, наличие coder/FreeType и право записи — отдельные зависимости.

На официальной странице нет собственного примера кода. Ниже добавлены два самостоятельных применения с входом, ожидаемым выводом и настоящим изображением.

Полный исходный XML с описанием, параметрами, возвратом, ошибками и историей
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.setimagebordercolor">
 <refnamediv>
  <refname>Imagick::setImageBorderColor</refname>
  <refpurpose>Sets the image border color</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::setImageBorderColor</methodname>
   <methodparam><type>mixed</type><parameter>border</parameter></methodparam>
  </methodsynopsis>
  <para>
   Sets the image border color.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>border</parameter></term>
     <listitem>
      <para>
       The border color
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   &imagick.imagick.throws;
  </para>
 </refsect1>

 <refsect1 role="changelog">
  &reftitle.changelog;
  <para>
   <informaltable>
    <tgroup cols="2">
     <thead>
      <row>
       <entry>&Version;</entry>
       <entry>&Description;</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>PECL imagick 2.1.0</entry>
       <entry>
        Now allows a string representing the color as a parameter.
        Previous versions allow only an ImagickPixel object.
       </entry>
      </row>
     </tbody>
    </tgroup>
   </informaltable>
  </para>
 </refsect1>

</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Задать цвет строкой и увидеть отдельный момент рисования

Setter вернул bool true и сохранил цвет для текущего изображения. До borderImage исходные пиксели и размер не изменились. После отдельного потребителя появился реальный синий бордюр12px по каждой стороне; итог424×344 и тёмный просмотр сохранены.

Задать цвет строкой и увидеть отдельный момент рисованияПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$prepared=clone $source;$ok=$prepared->setImageBorderColor('#226b82');$after=borderState($prepared);
saveBorderPNG($prepared,'set-property-only.png');
$prepared->borderImage($prepared->getImageBorderColor(),12,12);saveBorderPNG($prepared,'set-actual-border.png');
saveBorderPNG(borderPreview(new Imagick(__DIR__.'/set-actual-border.png'),'#243c4d'),'set-border-dark.png',false);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/set-property-only.png')),borderPreview(new Imagick(__DIR__.'/set-actual-border.png'))], 'border-set-minimal.png');
saveBorderDiagnostic('polaroid-border-setimagebordercolor-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'set-minimal','return_type'=>get_debug_type($ok),'return_value'=>$ok,'property_only_state'=>$after,'property_only_source_exact'=>$before===$after,'color'=>borderColorInfo($prepared->getImageBorderColor()),'outputs'=>['set-actual-border.png'=>borderState($prepared)]]);
echo "border-set-minimal.png\nset-property-only.png\nset-actual-border.png\nset-border-dark.png\nmetrics.json\n";
printf("ok=%d property-only-exact=%d final=%dx%d\n",(int)$ok,(int)($before===$after),$prepared->getImageWidth(),$prepared->getImageHeight());

Setter вернул bool true и сохранил цвет для текущего изображения. До borderImage исходные пиксели и размер не изменились. После отдельного потребителя появился реальный синий бордюр12px по каждой стороне; итог424×344 и тёмный просмотр сохранены. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-set-minimal.png
set-property-only.png
set-actual-border.png
set-border-dark.png
metrics.json
ok=1 property-only-exact=1 final=424x344

Использовать строку и ImagickPixel в двух бумажных пресетах

Два пресета показывают поддерживаемые формы входа: строка и ImagickPixel. Native Polaroid действительно использует border_color для бумаги. Цвет тени задан отдельно через background_color. Обе карточки честно сохраняют видимую TODO FIXME этой обёртки; настройка бумаги не решает ограничение подписи.

Использовать строку и ImagickPixel в двух бумажных пресетахПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$presets=['cream'=>'#fff4dc','blue'=>new ImagickPixel('#226b82')];$outputs=[];$returns=[];$colors=[];
foreach($presets as $name=>$color){
    $card=clone $source;$returns[$name]=$card->setImageBorderColor($color);$colors[$name]=borderColorInfo($card->getImageBorderColor());
    $card->setImageBackgroundColor('#243c4d');$card->polaroidImage(borderDraw($font,20),0);
    saveBorderPNG($card,$name.'-paper.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/'.$name.'-paper.png'),'#243c4d'),$name.'-paper-dark.png',false);$outputs[$name.'-paper.png']=borderState($card);
}

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/cream-paper.png')),borderPreview(new Imagick(__DIR__.'/blue-paper.png'))], 'border-set-presets.png');
saveBorderDiagnostic('polaroid-border-setimagebordercolor-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'set-workflow','returns'=>$returns,'colors'=>$colors,'outputs'=>$outputs,'caption_limit'=>'Both actual polaroidImage outputs retain visible TODO FIXME in this IM7 wrapper']);
echo "border-set-presets.png\ncream-paper.png\ncream-paper-dark.png\nblue-paper.png\nblue-paper-dark.png\nmetrics.json\n";
printf("presets=2 string-ok=%d pixel-ok=%d source-unchanged=%d\n",(int)$returns['cream'],(int)$returns['blue'],(int)($before===borderState($source)));

Два пресета показывают поддерживаемые формы входа: строка и ImagickPixel. Native Polaroid действительно использует border_color для бумаги. Цвет тени задан отдельно через background_color. Обе карточки честно сохраняют видимую TODO FIXME этой обёртки; настройка бумаги не решает ограничение подписи. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
border-set-presets.png
cream-paper.png
cream-paper-dark.png
blue-paper.png
blue-paper-dark.png
metrics.json
presets=2 string-ok=1 pixel-ok=1 source-unchanged=1
Imagick::polaroidImageИзменяет текущее изображение и возвращает bool true при успехе; результат не новый объект, если вы сами не создали clone.

PECL imagick 2, PECL imagick 3 · imagick

Imagick::polaroidImage(ImagickDraw $settings, float $angle): bool

Понятие и самый маленький вызов

Растр — сетка пикселей. RGB задаёт три цвета, alpha — прозрачность. $image — переменная с объектом; = присваивает, -> вызывает метод, () содержит аргументы, ; заканчивает инструкцию. new Imagick($path) читает файл, clone создаёт независимую рабочую копию. Цвет в кавычках — строка: #fff4dc задаёт красную FF=255, зелёную F4=244 и синюю DC=220 компоненты. Это не размеры рамки. Подробнее: переменные, объекты и методы, alpha и фон.

Создать эффект бумажного снимка: настоящие сохранённые изображения и явные границы операции
Создать эффект бумажного снимка: настоящие сохранённые изображения и явные границы операции
$settings = new ImagickDraw();
$settings->setFont(__DIR__ . '/font.ttf');
$settings->setFontSize(20);
$settings->setFillColor('#173c49');
$ok = $image->polaroidImage($settings, 0);

ImagickDraw хранит параметры рисования, а не изображение. Здесь20 — размер шрифта в points, не толщина рамки; локальный font.ttf задаёт воспроизводимый шрифт. __DIR__ — папка программы, . соединяет строки пути. Угол0 не отключает эффект. Метод меняет $image; если нужен исходник, сначала $image = clone $source. Полная программа сохраняет PNG с новой геометрией и показывает всю тень.

Полный базовый контракт

Создать эффект бумажного снимка

Imagick::polaroidImage(ImagickDraw $settings, float $angle): bool
ПараметрЧто он означает
$properties: ImagickDraw в XML; имя settings в Imagick 3.8.1Обязательный объект параметров рисования: для нашего текста явные font, font size и fill.
$angle: floatОбязательный угол поворота в градусах. Ноль всё равно выполняет бумагу/изгиб/тень/trim.

Изменяет текущее изображение и возвращает bool true при успехе; результат не новый объект, если вы сами не создали clone.

Доступность по официальному справочнику: PECL imagick 2, PECL imagick 3. Операция относится к текущему изображению объекта; для списка кадров выбирайте их и обрабатывайте осознанно.

Официальное описание указывает, что метод доступен, если Imagick скомпилирован против ImageMagick 6.3.2 или новее. В XML первый параметр properties, а в проверенном Imagick 3.8.1 его имя settings; позиционный вызов не зависит от различия имён. Полная исходная сигнатура:

Imagick::polaroidImage(ImagickDraw $properties, float $angle): bool

По native цепочке сначала строится бумажный растр с цветом border_color и источник накладывается OVER. Внутренняя бумага становится непрозрачной; затем создаются изгиб, тень, поворот и trim. Новая внешняя alpha принадлежит результату эффекта, а не является неизменённой alpha исходного предмета. background_color даёт цвет тени этому потребителю; наружное пространство перед окончательным Rotate снова становится none. Итоговые width/height и virtual page offset могут отличаться от исходных.

Важное ограничение именно Imagick 3.8.1 с IM7: PHP-обёртка polaroidImage передаёт в C буквальную подпись TODO FIXME и Bilinear interpolation. У этого метода нет аргумента caption. setImageProperty("caption", ...) не заменяет этот аргумент: в реальном контроле разные property дали одинаковый растр. Не прячьте полученную надпись и не выдавайте её за настройку пользователя. В этой сборке отдельный polaroidWithTextAndMethod(ImagickDraw $settings, float $angle, string $caption, int $method) передаёт собственный текст. Доступность проверяется method_exists; используем явный INTERPOLATE_BILINEAR. Это отдельный метод для явного текста и способа интерполяции. Для иной сборки отдельно проверьте её binding; ручная компоновка и annotateImage остаются другой явной альтернативой.

Ошибки должны обрабатываться на соответствующей стадии. Для пустых объектов getter, setter и polaroidImage реальный запуск выбросил ImagickException. Нераспознанная строка цвета дала ImagickException с Unrecognized color string. Проверка отсутствующего font.ttf завершилась в ImagickDraw::setFont до вызова Polaroid: это ошибка подготовки Draw, нельзя приписывать её выполнению эффекта. Неверный PHP-тип аргумента также проверяет PHP. Чтение пути, наличие coder/FreeType и право записи — отдельные зависимости.

Полный исходный официальный пример 1


<?php
/* Create the object */
$image = new Imagick('source.png');

/* Set the opacity */
$image->polaroidImage(new ImagickDraw(), 25);

/* output the image */
header('Content-type: image/png');
echo $image;

?>

Комментарий Set the opacity в оригинале неточно описывает действие: polaroidImage создаёт целый эффект снимка, а не просто устанавливает opacity. source.png должен существовать. Неявный шрифт new ImagickDraw() зависит от окружения; наши архивы включают явный локальный TTF и его лицензию. Content-Type сам не меняет формат содержимого: при другом входе следует явно выбрать PNG до бинарной выдачи. Наш CLI сохраняет файлы и печатает диагностику отдельно от HTTP-ответа.

Полный исходный XML с описанием, параметрами, возвратом, ошибками и историей
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook" xml:id="imagick.polaroidimage">
 <refnamediv>
  <refname>Imagick::polaroidImage</refname>
  <refpurpose>Simulates a Polaroid picture</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <modifier>public</modifier> <type>bool</type><methodname>Imagick::polaroidImage</methodname>
   <methodparam><type>ImagickDraw</type><parameter>properties</parameter></methodparam>
   <methodparam><type>float</type><parameter>angle</parameter></methodparam>
  </methodsynopsis>

  <para>
   Simulates a Polaroid picture. &imagick.method.available.0x632;
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>properties</parameter></term>
     <listitem>
      <para>
       The polaroid properties
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>angle</parameter></term>
     <listitem>
      <para>
       The polaroid angle
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>

 </refsect1>
 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   &imagick.return.success;
  </para>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title>A <function>Imagick::polaroidImage</function> example</title>
    <para>
     An example of using Imagick::polaroidImage()
    </para>
    <programlisting role="php">
<![CDATA[
<?php
/* Create the object */
$image = new Imagick('source.png');

/* Set the opacity */
$image->polaroidImage(new ImagickDraw(), 25);

/* output the image */
header('Content-type: image/png');
echo $image;

?>
]]>
    </programlisting>
   </example>
  </para>
 </refsect1>


</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->

Создать настоящий Polaroid даже при угле0

Угол0 не делает операцию нейтральной: native эффект добавил бумагу, изгиб, тень, буквальную подпись и изменил размер до448×388. Метод изменяет рабочую clone-копию и возвращает bool. Внешняя alpha результата создана эффектом; это не прежняя alpha исходного предмета.

Создать настоящий Polaroid даже при угле0Пример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$card=clone $source;$card->setImageBorderColor('#fff4dc');$card->setImageBackgroundColor('#243c4d');
$settings=borderDraw($font,20);$ok=$card->polaroidImage($settings,0);
saveBorderPNG($card,'polaroid-zero.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/polaroid-zero.png'),'#243c4d'),'polaroid-zero-dark.png',false);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/polaroid-zero.png'))], 'polaroid-minimal.png');
saveBorderDiagnostic('polaroid-border-polaroidimage-minimal', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'polaroid-minimal','return_type'=>get_debug_type($ok),'return_value'=>$ok,'angle'=>0.0,'paper'=>'#fff4dc','shadow'=>'#243c4d','caption'=>'TODO FIXME (literal IM7 wrapper)','outputs'=>['polaroid-zero.png'=>borderState($card)]]);
echo "polaroid-minimal.png\npolaroid-zero.png\npolaroid-zero-dark.png\nmetrics.json\n";
printf("ok=%d size=%dx%d source-unchanged=%d\n",(int)$ok,$card->getImageWidth(),$card->getImageHeight(),(int)($before===borderState($source)));

Угол0 не делает операцию нейтральной: native эффект добавил бумагу, изгиб, тень, буквальную подпись и изменил размер до448×388. Метод изменяет рабочую clone-копию и возвращает bool. Внешняя alpha результата создана эффектом; это не прежняя alpha исходного предмета. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-minimal.png
polaroid-zero.png
polaroid-zero-dark.png
metrics.json
ok=1 size=448x388 source-unchanged=1

Выбрать угол и отдельно передать желаемую native подпись

Полные PNG углов−12/0/+12 позволяют выбрать компоновку, сохранив все тени. Размер±12 здесь518×472, его нельзя обрезать под исходные400×320. Для собственного текста вызывается доступный IM7 companion с явными caption/interpolation; это другой метод, не обещание, что property caption заработал у polaroidImage.

Выбрать угол и отдельно передать желаемую native подписьПример для указанного окружения
<?php
declare(strict_types=1);
require __DIR__.'/polaroid-fixture.php';
restoreBorderInputs();
$source=new Imagick(__DIR__.'/source.png');
$before=borderState($source);$sourceWhite=borderPreview($source);
$font=__DIR__.'/font.ttf';
$outputs=[];
foreach(['minus12'=>-12.0,'zero'=>0.0,'plus12'=>12.0] as $name=>$angle){
    $card=clone $source;$card->setImageBorderColor('#fff4dc');$card->setImageBackgroundColor('#243c4d');
    $card->polaroidImage(borderDraw($font,20),$angle);saveBorderPNG($card,'angle-'.$name.'.png');$outputs['angle-'.$name.'.png']=borderState($card);
}
$ordinary=new Imagick(__DIR__.'/angle-zero.png');saveBorderPNG(borderPreview($ordinary,'#243c4d'),'angle-zero-dark.png',false);
if(!method_exists(Imagick::class,'polaroidWithTextAndMethod')){throw new RuntimeException('Explicit native caption companion not available');}
$captioned=clone $source;$captioned->setImageBorderColor('#fff4dc');$captioned->setImageBackgroundColor('#243c4d');
$captioned->polaroidWithTextAndMethod(borderDraw($font,20),0,'MUG 01 / NEW',Imagick::INTERPOLATE_BILINEAR);
saveBorderPNG($captioned,'actual-caption.png');saveBorderPNG(borderPreview(new Imagick(__DIR__.'/actual-caption.png'),'#243c4d'),'actual-caption-dark.png',false);$outputs['actual-caption.png']=borderState($captioned);

$rects=saveBorderComparison([$sourceWhite,borderPreview(new Imagick(__DIR__.'/angle-minus12.png')),borderPreview(new Imagick(__DIR__.'/angle-plus12.png')),borderPreview(new Imagick(__DIR__.'/actual-caption.png'))], 'polaroid-angle-caption.png');
saveBorderDiagnostic('polaroid-border-polaroidimage-workflow', ['source_before'=>$before,'source_after'=>borderState($source),'panel_geometry'=>$rects,'font_sha256'=>hash_file('sha256',$font)]+['kind'=>'polaroid-workflow','angles'=>['minus12'=>-12.0,'zero'=>0.0,'plus12'=>12.0],'ordinary_caption'=>'TODO FIXME','actual_caption'=>'MUG 01 / NEW','caption_method'=>'polaroidWithTextAndMethod','interpolation'=>Imagick::INTERPOLATE_BILINEAR,'outputs'=>$outputs]);
echo "polaroid-angle-caption.png\nangle-minus12.png\nangle-zero.png\nangle-plus12.png\nangle-zero-dark.png\nactual-caption.png\nactual-caption-dark.png\nmetrics.json\n";
printf("angles=3 caption-method=polaroidWithTextAndMethod source-unchanged=%d\n",(int)($before===borderState($source)));

Полные PNG углов−12/0/+12 позволяют выбрать компоновку, сохранив все тени. Размер±12 здесь518×472, его нельзя обрезать под исходные400×320. Для собственного текста вызывается доступный IM7 companion с явными caption/interpolation; это другой метод, не обещание, что property caption заработал у polaroidImage. Сохраните example.php и четыре дополнительных файла из архива в одной папке. Запустите php example.php с расширением Imagick и PNG/FreeType. Helper восстанавливает source.png и font.ttf с SHA-проверкой; лицензия шрифта включена. Нужна запись в эту папку. Сравнительные PNG содержат полные результаты натурального размера, не обрезанные исходным холстом. Все новые API-вызовы видны в программе; helper не вызывает getImageBorderColor, setImageBorderColor, polaroidImage или companion.

Ожидаемый вывод и созданные файлы
polaroid-angle-caption.png
angle-minus12.png
angle-zero.png
angle-plus12.png
angle-zero-dark.png
actual-caption.png
actual-caption-dark.png
metrics.json
angles=3 caption-method=polaroidWithTextAndMethod source-unchanged=1
Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.