Search code examples
iosuiimageviewuiimageuigraphicscontext

Drawing a circular image on top of another image - UIGraphicsBeginImageContextWithOptions


I've been struggling with this method for a while. I am drawing an avatar on top of another image. The user picture I want to be a circle, however I can't seem to figure out how. The user picture is a UIImage and not a UIImageView. I am aware of how to make a circle if it is an imageview. Below is the code. There might be a better approach.

-(UIImage *)drawImage:(UIImage*)pinImage withBadge:(UIImage *)user{



    UIGraphicsBeginImageContextWithOptions(pinImage.size, NO, 0.0f);
    [pinImage drawInRect:CGRectMake(0, 0, pinImage.size.width, pinImage.size.height)];
    [user drawInRect:CGRectMake(20.0, 10.0, user.size.width/2, user.size.height/2)];
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return resultImage;

}

The result is good, but the user image is still square, it is not circle. I have tried making the add the User image to a UIImageView, transform it to a circle, and then use it in the method by calling yourImageView.image, but no luck. I also tried numerous other ways. My logic is more than likely incorrect.

The desired outcome is a rounded image place on top of a pin/annotation. Where the black dot would be an image (a bigger circle than this).

enter image description here


Solution

  • You can clip the image context to the path of an image

    // Start the image context
    UIGraphicsBeginImageContextWithOptions(pinImage.size, NO, 0.0);
    UIImage *resultImage = nil;
    
    // Get the graphics context
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // Draw the first image
    [pinImage drawInRect:CGRectMake(0, 0, pinImage.size.width, pinImage.size.height)];
    
    // Get the frame of the second image
    CGRect rect = CGRectMake(20.0, 10.0, user.size.width/2, user.size.height/2)
    
    // Add the path of an ellipse to the context
    // If the rect is a square the shape will be a circle
    CGContextAddEllipseInRect(context, rect);
    // Clip the context to that path
    CGContextClip(context);
    
    // Do the second image which will be clipped to that circle
    [user drawInRect:rect];
    
    // Get the result
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); 
    
    // End the image context
    UIGraphicsEndImageContext();