Search code examples
iphoneobjective-ciosuiimageviewuiimage

Draw a border and shadow onto a UIImage


I have been able to redraw a UIImage with a border successfully, but not with a border + shadow. The code below successfully draws the image with a white border, but I cannot figure out how to include a drop shadow under the border. Help is greatly appreciated!

- (UIImage *)generatePhotoFrameWithImage:(UIImage *)image {
    CGSize newSize = CGSizeMake(image.size.width + 50, image.size.height + 60);
    UIGraphicsBeginImageContext(newSize);
    CGRect rect = CGRectMake(25, 35, image.size.width, image.size.height);
    [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextStrokeRectWithWidth(context, CGRectMake(25, 35, image.size.width, image.size.height), 50);
    
    //CGContextSetShadowWithColor(context, CGSizeMake(0, -60), 5, [UIColor blackColor].CGColor);
    
    UIImage *result =  UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

PS: I am not using a UIImageView because I need to preserve the full image quality.


Solution

  • You need to call CGContextSetShadowWithColor before you stroke the border, so the border will cast a shadow.

    If you don't want the border to cast a shadow onto the image, you need to set up a transparency layer in which you draw both the image and the border. You can read about transparency layers in the Quartz 2D Programming Guide.

    If you want to preserve image quality, you need to use UIGraphicsBeginImageContextWithOptions and pass in the scale of the original image.

    - (UIImage *)generatePhotoFrameWithImage:(UIImage *)image {
        CGSize newSize = CGSizeMake(image.size.width + 50, image.size.height + 60);
        CGRect rect = CGRectMake(25, 35, image.size.width, image.size.height);
    
        UIGraphicsBeginImageContextWithOptions(newSize, NO, image.scale); {
            CGContextRef context = UIGraphicsGetCurrentContext();
    
            CGContextBeginTransparencyLayer(context, NULL); {
                [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];
    
                CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
                CGContextSetShadowWithColor(context, CGSizeMake(0, 5), 5, [UIColor blackColor].CGColor);
                CGContextStrokeRectWithWidth(context, CGRectMake(25, 35, image.size.width, image.size.height), 50);
            } CGContextEndTransparencyLayer(context);
        }
        UIImage *result =  UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return result;
    }