Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Put border around partially transparent Image being drawn on CGContext

I have an image with a yellow vase in the foreground and transparent background:

enter image description here

I'm drawing it on a CGContext:

CGContextDrawImage(context, CGRectMake(0, 0, 100, 100), myImage.CGImage);

I can draw a shadow around it by using the following statement before CGContextDrawImage:

CGContextSetShadowWithColor(context, CGSizeMake(0,0), 5, [UIColor blueColor].CGColor);

enter image description here

But I want to put a stroke around the image, so that it'll looks like following:

enter image description here

If I did this:

CGContextSetRGBStrokeColor(shadowContext, 0.0f, 0.0f, 1.0f, 1.0f);
CGContextSetLineWidth(shadowContext, 5);
CGContextStrokeRect(shadowContext, CGRectMake(0, 0, 100, 100));

It (obviously) draws a rectangular border around the whole iamge like this:

enter image description here

Which is not what I need.

But what's the best way to draw the border as in the third image?

Please note that it's not possible to use UIImageView in this case, so using the properties of CALayer of UIImageView is not applicable.

like image 608
Sanjay Chaudhry Avatar asked Feb 15 '13 20:02

Sanjay Chaudhry


1 Answers

One way to do this is to use the mathematical morphology operator of dilation to "grow" the alpha channel of the image outward, then use the resulting grayscale image as a mask to simulate a stroke. By filling the dilated mask, then drawing the main image on top, you get the effect of a stroke. I've created a demo showing this effect, available on Github here: https://github.com/warrenm/Morphology (all source is MIT licensed, should it prove useful to you).

And here's a screenshot of it in action:

enter image description here

Note that this is staggeringly slow (dilation requires iteration of a kernel over every pixel), so you should pick a stroke width and precompute the mask image for each of your source images in advance.

like image 189
warrenm Avatar answered Nov 03 '22 06:11

warrenm