У меня есть изображение с прозрачным фоном, которое я хотел бы обвести контуром в 5 пикселей. В фотошопе я могу погладить это, чтобы добиться этого.
Я пытался использовать borderImage
но это не очертит пингвина.
$image = new Imagick();
$image->readImage('tux.png');
$image->borderImage(new ImagickPixel('red'), 5, 5); // no outline
Это изображение.
Это то, чего я хочу достичь.
Я начну с командной строки и, возможно, сделаю PHP позже, или позволю вам поработать над этим …
Шаг 1 — Извлечь прозрачность
Как вы видели, -border
обрисовывает в общих чертах все изображение, но вы на самом деле хотите наметить непрозрачный только области, поэтому вам нужно работать с прозрачностью или альфа-слоем. Давайте сначала извлечем это:
convert tux.png -alpha extract alpha.png
Шаг 2 — Получить края непрозрачной области
Теперь вы хотите, чтобы края этого изложены, поэтому я буду использовать -morphology
:
convert alpha.png -morphology edge octagon -threshold 50% edge.png
Я слышал, что у людей возникают проблемы с морфологическими операциями в PHP, поэтому здесь есть альтернативный метод для этого шага, который не использует морфологию. По сути, он дублирует альфа-слой, а затем использует статистику, чтобы найти самый яркий пиксель в каждом блоке 3×3 (который будет иметь эффект только на краях, где есть несколько черных и несколько белых пикселей в блоке 3×3), а затем различия результат с оригиналом, чтобы показать затронутые пиксели. Проще просто сделать, чем описать!
convert alpha.png \( +clone -statistic maximum 3x3 -threshold 50% \) -compose difference -composite edge.png
Используйте коробку 5×5 для жирной линии.
Я вижу, что есть -edge 5
вариант, который намного проще — мы живем и учимся!
Шаг 3 — Сделайте края красными и оставайтесь прозрачными
Теперь вы хотите, чтобы белый был красным, а черный — прозрачным:
convert edge.png -fill red -opaque white -transparent black rededge.png
Шаг 4 — Композитный красный контур поверх оригинала
И, наконец, вы хотите объединить это с вашим оригиналом:
convert tux.png rededge.png -composite result.png
Вся свинья
Или, вы можете сделать все это за один раз, как это:
convert tux.png \( +clone -alpha extract -morphology edge octagon -threshold 50% -fill red -opaque white -transparent black \) -composite result.png
Вы можете предпочесть более тонкий эффект -morphology edgeout
над -morphology edge
,
Версия PHP
Мои навыки PHP «низкий», но я начал и делаю некоторый прогресс — обновлю позже, но пока это выглядит так:
$image = new Imagick("tux.png");
$alpha = clone $image;
$alpha->separateImageChannel(Imagick::CHANNEL_ALPHA);
$alpha->negateImage(true);
$alpha->edgeImage(5);
$alpha->opaquePaintImage("white","red",65000,FALSE);
$alpha->transparentPaintImage("black",0.0,0,FALSE);
$image->compositeImage($alpha,Imagick::COMPOSITE_DEFAULT,0,0);
$image->writeImage("result.png");
Похоже, это работает, но некоторые аспекты, вероятно, можно было бы привести в порядок, особенно 65000
магическое число и, возможно, какое-то ненужное клонирование и прочее — я оставлю это вам!
Других решений пока нет …