3

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!

Community
  • 1
  • 1
Rohan Vasishth
  • 241
  • 1
  • 6
  • 14

3 Answers3

6

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

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • I know what I am about to ask is probably obvious but can you explain how I would use implement your solution in my code with my variable of downloadedImage – Rohan Vasishth Apr 10 '17 at 16:57
  • 4
    It's a nice sunny day here, so I've updated my answer, but really, you need to try and figure some of this stuff out for yourself. – Ashley Mills Apr 10 '17 at 17:00
5

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
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
0

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;
}
Oleg G.
  • 550
  • 5
  • 25