如何在iPhone SDK中将方形图像蒙上一个圆angular的图像?

你怎么能把一个正方形的图像掩盖成一个圆angular的图像呢?

你可以使用CoreGraphics为这个代码片段创build一个圆形矩形的path:

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) { float fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM (context, ovalWidth, ovalHeight); fw = CGRectGetWidth (rect) / ovalWidth; fh = CGRectGetHeight (rect) / ovalHeight; CGContextMoveToPoint(context, fw, fh/2); CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); CGContextClosePath(context); CGContextRestoreGState(context); } 

然后调用CGContextClip(context); 将其剪切到矩形path。 现在,任何完成的绘图(包括绘制图像)都将被裁剪为圆形的矩形形状。

举个例子,假设“image”是一个UIImage,并且在一个drawRect:方法中:

 CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); addRoundedRectToPath(context, self.frame, 10, 10); CGContextClip(context); [image drawInRect:self.frame]; CGContextRestoreGState(context); 

这是iPhone 3.0及更高版本中更简单的方法。 每个基于视图的对象都有一个关联的图层。 每个图层都可以有一个圆angular半径设置,这会给你正是你想要的:

 UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]]; // Get the Layer of any view CALayer * layer = [roundedView layer]; [layer setMasksToBounds:YES]; [layer setCornerRadius:10.0]; // You can even add a border [layer setBorderWidth:4.0]; [layer setBorderColor:[[UIColor blueColor] CGColor]]; 

要使用这些方法,您可能需要添加:

 #import <QuartzCore/QuartzCore.h> 

我意识到这是一个旧消息,只是为了简化它:

这里有两个可能的问题:(1)如何将圆angular应用于将显示在屏幕上的UIView(例如UIImageView),以及(2)如何遮盖正方形图像(即UIImage )来产生具有圆angular的新图像。

对于(1),最简单的方法是使用CoreAnimation并设置view.layer.cornerRadius属性

  // Because we're using CoreAnimation, we must include QuartzCore.h // and link QuartzCore.framework in a build phases #import <QuartzCore/QuartzCore.h> // start with an image UIImage * fooImage = [UIImage imageNamed:@"foo.png"]; // put it in a UIImageView UIView * view = [UIImageView alloc] initWithImage:fooImage]; // round its corners. This mask now applies to the view's layer's *background* view.layer.cornerRadius = 10.f // enable masksToBounds, so the mask applies to its foreground, the image view.layer.masksToBounds = YES; 

对于(2),最好的方法是使用UIKitgraphics操作:

 // start with an image UIImage * fooImage = [UIImage imageNamed:@"foo.png"]; CGRect imageRect = CGRectMake(0, 0, fooImage.size.width, fooImage.size.height); // set the implicit graphics context ("canvas") to a bitmap context for images UIGraphicsBeginImageContextWithOptions(imageRect.size,NO,0.0); // create a bezier path defining rounded corners UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:10.f]; // use this path for clipping in the implicit context [path addClip]; // draw the image into the implicit context [fooImage drawInRect:imageRect]; // save the clipped image from the implicit context into an image UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext(); // cleanup UIGraphicsEndImageContext(); 

问题(2)有些棘手,你可能会认为你可以使用CoreAnimation中的view.layer.mask属性来完成整个操作。 但是你不能这样做,因为CALayer的renderInContext:方法,你可以使用这个方法来从蒙版图层生成一个UIImage,它似乎忽略了这个蒙版。 更糟糕的是, renderInContext:的文档没有提到这一点,只提到了OSX 10.5的行为。

一些进一步的上下文:(2)的上述方法是使用UIKit的更多基本的CoreGraphicsfunction的包装。 你可以直接使用CoreGraphics调用来做同样的事情 – 这就是所select的答案所做的事情 – 但是你需要从曲线和线条手动构build圆angular矩形bezierpath,并且还需要补偿CoreGraphics使用绘制相对于UIKit的坐标系。

看到这个post – 很简单的答案

如何设置iphone中的UI图像圆angular

 UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]]; // Get the Layer of any view CALayer * l = [roundedView layer]; [l setMasksToBounds:YES]; [l setCornerRadius:10.0]; 

很简单。 self.profileImageView.layer.cornerRadius = self.profileImageView.frame.size.width / 2; self.profileImageView.clipsToBounds = YES;

对于每个视图,都有一个捆绑的图层属性。 所以上面的第一行是设置图层对象的angular半径(即CALayer类的一个实例)。 要从平方图像制作圆形图像,半径设置为UIImageView宽度的一半。 例如,如果平方图像的宽度是100像素。 半径设置为50像素。 其次,你必须将clipsToBounds属性设置为YES才能使图层正常工作。

这两种方法的工作,但差异显示取决于你在哪里使用它。

对于例如:如果您有一个表格视图,单元格显示图像以及其他标签等,并且您使用图层来设置cornerRadius,则滚动将会受到很大的打击。 它变得生涩。

当我在表格视图单元格中使用图层作为图像时,我遇到了这个问题,并试图找出造成这种急躁的原因只是发现CALayer是罪魁祸首。

用NilObject解释的drawRect中的第一个解决scheme。 这就像一个丝绸卷动平滑的魅力。

另一方面,如果你想在静态视图中使用这个,像popover视图等,layer是最简单的方法。

正如我所说,这两种方法都能很好地工作,只需要根据你想使用的地方来决定。

我使用这种方法。

 + (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size; { UIImage *img = nil; CGRect rect = CGRectMake(0, 0, size.width, size.height); UIGraphicsBeginImageContext(rect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillRect(context, rect); img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } 

build立在藻类之外 ,这里有一些很好的方法可以放入UIImage类:

 - (UIImage *) roundedCornerImageWithRadius:(CGFloat)radius { CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height); UIGraphicsBeginImageContextWithOptions(imageRect.size,NO,0.0); //scale 0 yields better results //create a bezier path defining rounded corners and use it for clippping UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:radius]; [path addClip]; // draw the image into the implicit context [self drawInRect:imageRect]; // get image and cleanup UIImage *roundedCornerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return roundedCornerImage; } + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size andCornerRadius:(CGFloat)radius { UIImage *image = nil; if (size.width == 0 || size.height == 0) { size = CGSizeMake(1.0, 1.0); } CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height); UIGraphicsBeginImageContextWithOptions(rect.size,NO,0.0); //yields sharper results than UIGraphicsBeginImageContext(rect.size) CGContextRef context = UIGraphicsGetCurrentContext(); if (context) { CGContextSetFillColorWithColor(context, [color CGColor]); if (radius > 0.0) { //create a bezier path defining rounded corners and use it for clippping UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius]; [path addClip]; CGContextAddPath(context, path.CGPath); } CGContextFillRect(context, rect); image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } return image; }