I have an application which requires that a solid black outline be drawn around a partly-transparent UIImage. Not around the frame of the image, but rather around all the opaque parts of the image itself. I.e., think of a transparent PNG with an opaque white “X” on it — I need to outline the “X” in black.
To make matters trickier, AFTER the outline is drawn, the opacity of the original image will be adjusted, but the outline must remain opaque — so the outline I generate has to include only the outline, and not the original image.
My current technique is this:
- Create a new
UIViewwhich has the dimensions of the original image. - Duplicate the
UIImage4 times and add the duplicates as subviews of theUIView, with eachUIImageoffset diagonally from the original location by a couple pixels. - Turn that
UIViewinto an image (via the typicalUIGraphicsGetImageFromCurrentImageContextmethod). - Using
CGImageMaskCreateandCGImageCreateWithMask, subtract the original image from this new image, so only the outline remains.
It works. Even with only the 4 offset images, the result looks quite good. However, it’s horribly inefficient, and causes a good solid 4-second delay on an iPhone 4.
So what I need is a nice, speedy, efficient way to achieve the same thing, which is fully supported by iOS 4.0.
Any great ideas? 🙂
I would like to point out that whilst a few people have suggested edge detection, this is not an appropriate solution. Edge detection is for finding edges within image data where there is no obvious exact edge representation in the data.
For you, edges are more well defined, you are looking for the well defined outline. An edge in your case is any pixel which is on a fully transparent pixel and next to a pixel which is not fully transparent, simple as that! iterate through every pixel in the image and set them to black if they fulfil these conditions.
Alternatively, for an anti-aliased result, get a boolean representation of the image, and pass over it a small anti-aliased circle kernel. I know you said custom filters are not supported, but if you have direct access to image data this wouldn’t be too difficult to implement by hand…
Cheers, hope this helps.