I recently needed to figure out how to implement a solution like this. Here is the code I use:
Code:
// This cropping method will render the imageToCrop into a new graphics context
// cropped by the greyscale image defined by cropToImage. The result is returned
// as a RGBA image. The result of this operation is an image where the greyscale
// pixel value is converted into the alpha channel for the pixels.
- (UIImage*)imageByCropping:(UIImage*)imageToCrop
cropToImage:(UIImage*)cropToImage
{
// create a context to do our clipping in
CGImageRef imageToCropRef = imageToCrop.CGImage;
CGImageRef cropToImageRef = cropToImage.CGImage;
size_t width = CGImageGetWidth(imageToCropRef);
size_t height = CGImageGetHeight(imageToCropRef);
CGSize size = CGSizeMake(width, height);
UIGraphicsBeginImageContext(size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
// Flip coordinate system
CGContextTranslateCTM(currentContext, 0.0, size.height);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Create a new image that is the size of the original image.
CGRect clippedRect = CGRectMake(0, 0, size.width, size.height);
CGContextClipToMask( currentContext, clippedRect, cropToImageRef);
CGRect drawRect = CGRectMake(0,
0,
imageToCrop.size.width,
imageToCrop.size.height);
// draw the image to our clipped context using our offset rect
CGContextDrawImage(currentContext, drawRect, imageToCrop.CGImage);
// pull the image from our cropped context
UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
// pop the context to get back to the default
UIGraphicsEndImageContext();
// Note: this is autoreleased
return cropped;
}
The trick is to generate a mask image that is a grayscale image, then the white parts are transparent and the black parts can't be seen. Anything in between becomes the alpha channel for the resulting image.