Outline a transparent image using imagick PHP

我的未来我决定 提交于 2019-12-05 02:49:36

I'll start at the command line and may do the PHP later, or let you work that bit out...

Step 1 - Extract transparency

As you have seen, -border outlines the whole image, but you actually want to outline the opaque areas only so you need to work with the transparency, or alpha layer. Let's extract that first:

convert tux.png -alpha extract alpha.png

Step 2 - Get edges of opaque area

Now, you want the edges of that outlined, so I'll use -morphology:

convert alpha.png -morphology edge octagon -threshold 50% edge.png

I have heard that folks are having difficulty with morphological operations in PHP, so here is an alternative method for this step that doesn't use morphology. Basically, it duplicates the alpha layer, and then uses statistics to find the brightest pixel in each 3x3 box (which is only going to have an effect at the edges where there are some black and some white pixels in the 3x3 box) and then differences the result with the original to show the affected pixels. Easier to just do than describe!

convert alpha.png \( +clone -statistic maximum 3x3 -threshold 50% \) -compose difference -composite edge.png

Use a 5x5 box for a fatter line.

I see there is an -edge 5 option which is way easier - we live and learn!

Step 3 - Make edges red and rest transparent

Now you want the white to be red and the black to be transparent:

convert edge.png -fill red -opaque white -transparent black rededge.png

Step 4 - Composite red outline over original

And finally, you want to composite that over your original:

convert tux.png rededge.png -composite result.png

The whole hog

Or, you can do it all in one go like this:

convert tux.png  \( +clone -alpha extract -morphology edge octagon -threshold 50% -fill red -opaque white -transparent black \) -composite result.png

You may prefer the more subtle effect of -morphology edgeout over -morphology edge.

PHP Version

My PHP skills are "low", but I have started and am making some progress - will update later, but so far it looks like this:

   $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");

That seems to pretty much work, but some aspects could probably be tidied up - specifically the 65000 magic number and maybe some unnecessary cloning and stuff -I'll leave that to you!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!