Создайте прозрачное изображение, используя Imagick Stack Overflow

У меня есть изображение с прозрачным фоном, которое я хотел бы обвести контуром в 5 пикселей. В фотошопе я могу погладить это, чтобы добиться этого.

Я пытался использовать borderImage но это не очертит пингвина.

$image = new Imagick();
$image->readImage('tux.png');

$image->borderImage(new ImagickPixel('red'), 5, 5); // no outline

Это изображение.

смокинг оригинальный

Это то, чего я хочу достичь.

смокинг

8

Решение

Я начну с командной строки и, возможно, сделаю 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 магическое число и, возможно, какое-то ненужное клонирование и прочее — я оставлю это вам!

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]