为圆形UIImage添加边框

3

我一直在研究许多Stack Overflow帖子,但是没有一篇能给我想要的解决方案。迄今为止,我已经能够使用AlamoFire获取图像并将其转换为圆形。然而,不幸的是,AlamoFire没有提供向UIImage添加边框的选项。我想知道是否有人有解决我的问题的方法。以下是使图像成为圆形的代码:

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
}

你可以看到我能够得到一个圆形的图像,但是没有边框。到目前为止,我已经尝试了许多在Stack Overflow上找到的解决方案来处理我的AlamoFire解决方案。以下是一些相关帖子:Making a UIImage to a circle formCut a UIImage into a circle Swift(iOS)。 这里是我目前拥有的:enter image description here 我想要的是这样的:enter image description here 如果有任何帮助,将不胜感激。谢谢!

展示你想要的最终结果的图片。这样会更容易尝试并提供帮助。 - DonMag
你想修改这张图片,还是只是在你的应用程序中呈现它? - Larme
@DonMag 我刚刚添加了一张我拥有的和我想要的图片。 - Rohan Vasishth
@Larme 我理想情况下只想把这张图片变成一个带边框的圆形。 - Rohan Vasishth
@AshleyMills 嗯,这就是整个问题所在。该图像是UIImage而不是UIImageView。 - Rohan Vasishth
显示剩余5条评论
3个回答

6
这应该创建一个带有白色边框的圆形图像...
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()
    }
}

那么,
let roundImage = round(image: downloadedImage)

enter image description here


我知道我即将要问的可能很明显,但您能否解释一下如何在我的代码中使用您的解决方案与我的变量downloadedImage吗? - Rohan Vasishth
4
这里是一个阳光明媚的好天气,所以我更新了我的回答,但实际上,你需要尝试自己去理解一些这方面的内容。 - Ashley Mills

5

我建议您按照以下步骤为包含UIImage的UIImageView应用所需的外观:

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

更新:

如果你正在使用Google Maps (GMSMarker),你应该通过编程方式创建一个UIImageView(将上面的代码片段应用到它),并将其作为iconView添加到你的标记中,如下所示:

marker.iconView = imageView

所以,它应该类似于:
// 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

是的,我已经尝试过了,但问题是我无法将UIImageView添加到我的marker.icon值中,因为该值必须是UIImage。 - Rohan Vasishth
是的,我正在使用谷歌地图,并且正在使用GMSMarker。 - Rohan Vasishth
你能够将 UIImageView 添加到标记上,检查一下更新 :) - Ahmad F
我试过了,但我现在正在处理这个错误:常量imageView在初始化之前被使用。 - Rohan Vasishth
非常感谢!!!我已经寻找这样的解决方案很长时间了。再次感谢您! - Rohan Vasishth
很高兴能帮忙 :) - Ahmad F

0
对于那些在处理@ashley回答中的Objective-C版本遇到困难的人来说,同样的逻辑。
+ (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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接