Rohan Vasishth
Rohan Vasishth

Reputation: 241

Add Border to circular UIImage

I have been looking at many stack overflow posts but none have them have been able to give me my desired solution. So far I have been able to get an image and convert it into a circle using AlamoFire. However, unfortunately alamo fire does not provide an option to add a border to a UIImage. I was wondering if anyone had a solution to my problem. Here is my code for making the image into a circle:

if let downloadedImage = UIImage(data: data!) {

   let markerImage = downloadedImage
   let markerImageSize = CGSize(width: 50, height: 50)
   let markerImageFilter = AspectScaledToFillSizeCircleFilter(size: markerImageSize)

   let finalMarkerImage = markerImageFilter.filter(markerImage)

   marker.icon = finalMarkerImage
}

As you can see I am able to get a circle but not one with a border. So far I have tried many stack overflow post solutions to try and work with my AlamoFire solution. Here are some of the posts: Making a UIImage to a circle form

Cut a UIImage into a circle Swift(iOS)

Here is what I currently have:

enter image description here

Here is what I want:

enter image description here

Any help would be much appreciated. Thanks!

Upvotes: 3

Views: 3558

Answers (3)

Oleg G.
Oleg G.

Reputation: 588

for people struggling with the obj-c version of @ashley answer. Same logic

+ (UIImage *)drawBorderToImage:(UIImage *)image withColor:(UIColor *)color andThickness:(CGFloat)thickness {
    CGFloat diameter = MIN(image.size.width, image.size.height);
    BOOL isLandscape = image.size.width > image.size.height;
    CGFloat xOffset = isLandscape ? (image.size.width - diameter) / 2 : 0;
    CGFloat yOffset = isLandscape ? 0 : (image.size.height - diameter) / 2;
    CGSize imageSize = CGSizeMake(diameter, diameter);
    UIGraphicsBeginImageContext(image.size);
    UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
    [ovalPath addClip];
    [image drawAtPoint:CGPointMake(-xOffset, -yOffset)];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, color.CGColor);
    ovalPath.lineWidth = thickness;
    [ovalPath stroke];
    UIImage *borderedImage =  UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return borderedImage;
}

Upvotes: 0

Ahmad F
Ahmad F

Reputation: 31645

I would suggest that you should apply the required appearance to the UIImageView that contains your UIImage, as follows:

imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 2
imageView.layer.borderColor = UIColor.brown.cgColor

Update:

Since you are working with Google Maps (GMSMarker), you should create an UIImageView programmatically (apply the above code snippet to it) and add it to your marker as iconView, as follows:

marker.iconView = imageView

So, it should be similar to:

// of course the values of the width/height (size) is up to you
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 2
imageView.layer.borderColor = UIColor.white.cgColor

// set your image
imageView.image = ...

marker.iconView = imageView

Upvotes: 5

Ashley Mills
Ashley Mills

Reputation: 53101

This should create round image with white border…

func round(image: UIImage) -> UIImage {
    let imageWidth = image.size.width
    let imageHeight = image.size.height

    let diameter = min(imageWidth, imageHeight)
    let isLandscape = imageWidth > imageHeight

    let xOffset = isLandscape ? (imageWidth - diameter) / 2 : 0
    let yOffset = isLandscape ? 0 : (imageHeight - diameter) / 2

    let imageSize = CGSize(width: diameter, height: diameter)

    return UIGraphicsImageRenderer(size: imageSize).image { _ in

        let ovalPath = UIBezierPath(ovalIn: CGRect(origin: .zero, size: imageSize))
        ovalPath.addClip()
        image.draw(at: CGPoint(x: -xOffset, y: -yOffset))
        UIColor.white.setStroke()
        ovalPath.lineWidth = diameter / 50
        ovalPath.stroke()
    }
}

Then

let roundImage = round(image: downloadedImage)

enter image description here

Upvotes: 6

Related Questions