I have an image with a transparent background that I’d like to outline with a 5px border. In photoshop, I can stroke it to achieve this.
I’ve tried using borderImage
but it won’t outline the penguin.
$image = new Imagick();
$image->readImage('tux.png');
$image->borderImage(new ImagickPixel('red'), 5, 5); // no outline
This is the image.
This is what I want to achieve.
2
Answers
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:Step 2 – Get edges of opaque area
Now, you want the edges of that outlined, so I’ll use
-morphology
: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 3×3 box (which is only going to have an effect at the edges where there are some black and some white pixels in the 3×3 box) and then differences the result with the original to show the affected pixels. Easier to just do than describe!
Use a 5×5 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:
Step 4 – Composite red outline over original
And finally, you want to composite that over your original:
The whole hog
Or, you can do it all in one go like this:
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:
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!enter image description here function getCharacterOutline() {
}