将 UIImage 制作成圆形

发布于 2024-12-04 10:26:40 字数 1603 浏览 1 评论 0原文

我一直在尝试将 UIImage 屏蔽成一个圆圈。 我现在使用的代码在其他答案中很流行,但是虽然我确实得到了一个圆圈,但它的边缘非常锯齿状且不平滑。 有人可以帮忙吗?我能得到一个完美、光滑的圆圈吗?

我用来创建面具的代码是:

  (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef imageNoAlpha = image.CGImage;

    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();

    CGFloat width = CGImageGetWidth(imageNoAlpha);
    CGFloat height = CGImageGetWidth(imageNoAlpha);

    CGContextRef ctxWithAlpha = CGBitmapContextCreate(nil, width, height, 8, 4*width, cs, kCGImageAlphaPremultipliedFirst);

    CGContextDrawImage(ctxWithAlpha, CGRectMake(0, 0, width, height), imageNoAlpha);

    CGImageRef imageWithAlpha = CGBitmapContextCreateImage(ctxWithAlpha);

    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);

    UIImage* retImage= [UIImage imageWithCGImage:masked];
    UIImage* retImageFixed = [retImage transparentBorderImage:1];

    CGImageRelease(mask);
    CGImageRelease(masked);
    CGImageRelease(imageWithAlpha);
    CGContextRelease(ctxWithAlpha);
    CGColorSpaceRelease(cs);

    return retImageFixed;

提前致谢......

I have been trying to mask a UIImage into a circle.
I'm using now the code that has been popular on other answers here, but although I do get a circle its edges are very jagged and not smooth.
Anyone can help? I do I get a perfect, smooth circle?

The code I'm using to create the mask is:

  (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef imageNoAlpha = image.CGImage;

    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();

    CGFloat width = CGImageGetWidth(imageNoAlpha);
    CGFloat height = CGImageGetWidth(imageNoAlpha);

    CGContextRef ctxWithAlpha = CGBitmapContextCreate(nil, width, height, 8, 4*width, cs, kCGImageAlphaPremultipliedFirst);

    CGContextDrawImage(ctxWithAlpha, CGRectMake(0, 0, width, height), imageNoAlpha);

    CGImageRef imageWithAlpha = CGBitmapContextCreateImage(ctxWithAlpha);

    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);

    UIImage* retImage= [UIImage imageWithCGImage:masked];
    UIImage* retImageFixed = [retImage transparentBorderImage:1];

    CGImageRelease(mask);
    CGImageRelease(masked);
    CGImageRelease(imageWithAlpha);
    CGContextRelease(ctxWithAlpha);
    CGColorSpaceRelease(cs);

    return retImageFixed;

Thanks in advance...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

合约呢 2024-12-11 10:26:40

尝试这个代码

yourImageView.layer.cornerRadius = yourImageView.frame.size.height /2;
yourImageView.layer.masksToBounds = YES;
yourImageView.layer.borderWidth = 0;

,显示像 ios 7 圆形图像一样的图像,谢谢

try this code

yourImageView.layer.cornerRadius = yourImageView.frame.size.height /2;
yourImageView.layer.masksToBounds = YES;
yourImageView.layer.borderWidth = 0;

this show image like ios 7 circle image thanks

我也只是我 2024-12-11 10:26:40

这可能会帮助您,将角半径作为要显示图像的参考视图的一半,或者您可以设置自定义矩形,

例如。就我而言,我想在 "imageView" 上显示图像,因此本例中的角半径为 imageView.frame.size.width/2

- (void)displayImage
{
    imageView.image = [self getRoundedRectImageFromImage:@"Test.png" onReferenceView:imageView withCornerRadius: imageView.frame.size.width/2];
}



- (UIImage *)getRoundedRectImageFromImage :(UIImage *)image onReferenceView :(UIImageView*)imageView withCornerRadius :(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:imageView.bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}

This might help you, pass corner radius as half of the reference view where you want to display the image or you can set a custom rect,

eg. In my case I want to display the image on a "imageView", so the corner radius in this case would be imageView.frame.size.width/2

- (void)displayImage
{
    imageView.image = [self getRoundedRectImageFromImage:@"Test.png" onReferenceView:imageView withCornerRadius: imageView.frame.size.width/2];
}



- (UIImage *)getRoundedRectImageFromImage :(UIImage *)image onReferenceView :(UIImageView*)imageView withCornerRadius :(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:imageView.bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}
源来凯始玺欢你 2024-12-11 10:26:40

抱歉格式很丑。
aToz 答案的更好版本。

@interface UIImage (CircleMask)

+ (UIImage *)roundedRectImageFromImage :(UIImage *)image
                                  size :(CGSize)imageSize
                      withCornerRadius :(float)cornerRadius;

@end

@implementation UIImage(CircleMask)

+(UIImage*)roundedRectImageFromImage:(UIImage *)image
                                size:(CGSize)imageSize
                    withCornerRadius:(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);   //  <= notice 0.0 as third scale parameter. It is important cause default draw scale ≠ 1.0. Try 1.0 - it will draw an ugly image..
    CGRect bounds = (CGRect){CGPointZero,imageSize};
    [[UIBezierPath bezierPathWithRoundedRect:bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}

@end

Swift 中同样的事情:

extension UIImage{

    class func roundedRectImageFromImage(image:UIImage,imageSize:CGSize,cornerRadius:CGFloat)->UIImage{
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 0.0)
        let bounds = CGRect(origin: CGPointZero, size: imageSize)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        image.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
    
}

Sorry for ugly formatting.
Better version of aToz's answer.

@interface UIImage (CircleMask)

+ (UIImage *)roundedRectImageFromImage :(UIImage *)image
                                  size :(CGSize)imageSize
                      withCornerRadius :(float)cornerRadius;

@end

@implementation UIImage(CircleMask)

+(UIImage*)roundedRectImageFromImage:(UIImage *)image
                                size:(CGSize)imageSize
                    withCornerRadius:(float)cornerRadius
{
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);   //  <= notice 0.0 as third scale parameter. It is important cause default draw scale ≠ 1.0. Try 1.0 - it will draw an ugly image..
    CGRect bounds = (CGRect){CGPointZero,imageSize};
    [[UIBezierPath bezierPathWithRoundedRect:bounds
                                cornerRadius:cornerRadius] addClip];
    [image drawInRect:bounds];
    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return finalImage;
}

@end

The same thing in Swift:

extension UIImage{

    class func roundedRectImageFromImage(image:UIImage,imageSize:CGSize,cornerRadius:CGFloat)->UIImage{
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 0.0)
        let bounds = CGRect(origin: CGPointZero, size: imageSize)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        image.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
    
}
停顿的约定 2024-12-11 10:26:40

aToz 和 fnc12 答案的更好版本(使用 Swift):

extension UIImage
{
    func roundImage() -> UIImage
    {
        let newImage = self.copy() as! UIImage
        let cornerRadius = self.size.height/2
        UIGraphicsBeginImageContextWithOptions(self.size, false, 1.0)
        let bounds = CGRect(origin: CGPointZero, size: self.size)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        newImage.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
}

用法:

self.userImageView.image = image.roundedImage()

A better version of aToz's and fnc12's answers (in Swift):

extension UIImage
{
    func roundImage() -> UIImage
    {
        let newImage = self.copy() as! UIImage
        let cornerRadius = self.size.height/2
        UIGraphicsBeginImageContextWithOptions(self.size, false, 1.0)
        let bounds = CGRect(origin: CGPointZero, size: self.size)
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).addClip()
        newImage.drawInRect(bounds)
        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return finalImage
    }
}

Usage:

self.userImageView.image = image.roundedImage()
吃素的狼 2024-12-11 10:26:40

感觉我应该把我的帽子扔进拳击场。有效、紧凑的 Swift 5 解决方案:

extension UIImage {

    var rounded: UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        defer { UIGraphicsEndImageContext() }
        let bounds = CGRect(origin: .zero, size: size)
        UIBezierPath(roundedRect: bounds, cornerRadius: size.height/2.0).addClip()
        draw(in: bounds)
        return UIGraphicsGetImageFromCurrentImageContext()
    }

}

Felt like I should throw my hat into the ring. An effective, compact Swift 5 solution:

extension UIImage {

    var rounded: UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        defer { UIGraphicsEndImageContext() }
        let bounds = CGRect(origin: .zero, size: size)
        UIBezierPath(roundedRect: bounds, cornerRadius: size.height/2.0).addClip()
        draw(in: bounds)
        return UIGraphicsGetImageFromCurrentImageContext()
    }

}

想挽留 2024-12-11 10:26:40

从 UIImageView 获取帮助怎么样

+ (UIImage *)circularImage:(UIImage *)image withDiameter:(NSUInteger)diameter
{
    CGRect frame = CGRectMake(0.0f, 0.0f, diameter, diameter);
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = YES;
    imageView.image = image;
    CALayer *layer = imageView.layer;


    layer.masksToBounds = YES;

    layer.cornerRadius =MAX( imageView.frame.size.height,imageView.frame.size.width)/2;

    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size,NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [layer renderInContext:context];


    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return roundedImage;
}

What about getting help from UIImageView

+ (UIImage *)circularImage:(UIImage *)image withDiameter:(NSUInteger)diameter
{
    CGRect frame = CGRectMake(0.0f, 0.0f, diameter, diameter);
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = YES;
    imageView.image = image;
    CALayer *layer = imageView.layer;


    layer.masksToBounds = YES;

    layer.cornerRadius =MAX( imageView.frame.size.height,imageView.frame.size.width)/2;

    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size,NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [layer renderInContext:context];


    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return roundedImage;
}
那请放手 2024-12-11 10:26:40

如果您使用 Swift,则可以导入“AlamofireImage”,并使用其函数之一。对于带圆圈的图像:

let roundImage = UIImage(named: "myImage")!.af_imageRoundedIntoCircle()

If you're using Swift, you can import 'AlamofireImage', and use one of its funcs. For circled image:

let roundImage = UIImage(named: "myImage")!.af_imageRoundedIntoCircle()
好多鱼好多余 2024-12-11 10:26:40

如果您使用 UIImageView 并且希望在保持圆角的同时对图像的大小进行动画处理,则可以按如下方式应用转换:

Objective-C

// Our UIImageView reference
@property (weak, nonatomic) IBOutlet UIImageView *myImageView;

- (void)viewDidLoad {
    [super viewDidLoad];

     myImageView.layer.cornerRadius = myImageView.frame.size.width / 2.0f;
     myImageView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.4f, 0.4f);
}

- (void)viewDidAppear:(BOOL)animated {
    [UIView animateWithDuration:1.0 animations:^{
        myImageView.transform = CGAffineTransformIdentity;
    }];
}

Swift

// Our UIImageView reference
@IBOutlet weak var myImageView:UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    myImageView.layer.cornerRadius = myImageView.frame.size.width / 2;
    myImageView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.4, 0.4)
}

override func viewDidAppear(animated: Bool) {
    UIView.animateWithDuration(1.0) {
        myImageView.transform = CGAffineTransformIdentity;
    }
}

注意:这还将保留任何自动布局约束

If you are using an UIImageView and you are looking to animate the size of the image while maintaining the rounded corners, you can apply a transformation as follows:

Objective-C

// Our UIImageView reference
@property (weak, nonatomic) IBOutlet UIImageView *myImageView;

- (void)viewDidLoad {
    [super viewDidLoad];

     myImageView.layer.cornerRadius = myImageView.frame.size.width / 2.0f;
     myImageView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.4f, 0.4f);
}

- (void)viewDidAppear:(BOOL)animated {
    [UIView animateWithDuration:1.0 animations:^{
        myImageView.transform = CGAffineTransformIdentity;
    }];
}

Swift

// Our UIImageView reference
@IBOutlet weak var myImageView:UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    myImageView.layer.cornerRadius = myImageView.frame.size.width / 2;
    myImageView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.4, 0.4)
}

override func viewDidAppear(animated: Bool) {
    UIView.animateWithDuration(1.0) {
        myImageView.transform = CGAffineTransformIdentity;
    }
}

NOTE: This will also maintain any AutoLayout constraints.

魄砕の薆 2024-12-11 10:26:40

我用 UIBezierPath 解决了我的问题

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;

I resolve my problem with UIBezierPath

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:yourImageView.bounds];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = path.CGPath;
yourImageView.layer.mask = maskLayer;
亢潮 2024-12-11 10:26:40

试试这个

UIImageView *circleImageview=[[UIImageView alloc]init];
circleImageview.frame=CGRectMake(0,10, 80, 80)]; 
circleImageview.layer.cornerRadius=circleimagview.frame.size.height/2;
 circleImageview.userInteractionEnabled=YES;
 [self.view addSubview:circleImageview];

注意:确保该视图的高度和宽度相同。

try this

UIImageView *circleImageview=[[UIImageView alloc]init];
circleImageview.frame=CGRectMake(0,10, 80, 80)]; 
circleImageview.layer.cornerRadius=circleimagview.frame.size.height/2;
 circleImageview.userInteractionEnabled=YES;
 [self.view addSubview:circleImageview];

Note:Make Sure height and width will be same of that view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文