一个简单的创建圆角图像的UIImage扩展实现

在iOS开发中经常需要用到圆角图像。简单搜索一下就能找到很多创建圆角图像的实现代码。我在Stack Overflow上找到了一段代码,略微修改了一下,写了个简单的Category方法,可以用来创建圆角图像。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* UIImage+RoundedRect.h*/
#import <UIKit/UIKit.h>

@interface UIImage (RoundedCorner)
- (UIImage *)roundedCornerImageWithCornerRadius:(CGFloat)cornerRadius;
@end

/* UIImage+RoundedRect.m*/

#import "UIImage+RoundedCorner.h"

@implementation UIImage (RoundedCorner)

- (UIImage *)roundedCornerImageWithCornerRadius:(CGFloat)cornerRadius {
    CGFloat w = self.size.width;
    CGFloat h = self.size.height;
    CGFloat scale = [UIScreen mainScreen].scale;
    // 防止圆角半径小于0,或者大于宽/高中较小值的一半。
    if (cornerRadius < 0)
        cornerRadius = 0;
    else if (cornerRadius > MIN(w, h))
        cornerRadius = MIN(w, h) / 2.;

    UIImage *image = nil;
    CGRect imageFrame = CGRectMake(0., 0., w, h);
    UIGraphicsBeginImageContextWithOptions(self.size, NO, scale);
    [[UIBezierPath bezierPathWithRoundedRect:imageFrame cornerRadius:cornerRadius] addClip];
    [self drawInRect:imageFrame];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end

把这个Category添加到项目中之后,直接对UIImage对象调用- roundedCornerImageWithCornerRadius:方法即可。以上实现并非最高效,最佳的实现,但是有时候Quick and Dirty的方法已经足够好了,是吧。(天音:你就自我安慰吧。)

#import  < Foundation / Foundation.h >

typedef 
enum  {
    UIImageRoundedCornerTopLeft 
=   1 ,
    UIImageRoundedCornerTopRight 
=   1   <<   1 ,
    UIImageRoundedCornerBottomRight 
=   1   <<   2 ,
    UIImageRoundedCornerBottomLeft 
=   1   <<   3
} UIImageRoundedCorner;

@interface UIImage (Utility)

// + (void)addRoundedRectToPath(CGContextRef context, CGRect rect, float radius, UIImageRoundedCorner cornerMask);

-  (UIImage  * )roundedRectWith:( float )radius cornerMask:(UIImageRoundedCorner)cornerMask;

@end

 

 实现文件

 

#import  " UIImage+Utility.h "

// UIKit坐标系统原点在左上角,y方向向下的(坐标系A),但在Quartz中坐标系原点在左下角,y方向向上的(坐标系B)。图片绘制也是颠倒的。
static   void  addRoundedRectToPath(CGContextRef context, CGRect rect,  float  radius, UIImageRoundedCorner cornerMask)
{
    
// 原点在左下方,y方向向上。移动到线条2的起点。
    CGContextMoveToPoint(context, rect.origin.x, rect.origin.y  +  radius);
    
    
// 画出线条2, 目前画线的起始点已经移动到线条2的结束地方了。
    CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y  +  rect.size.height  -  radius);
    
    
// 如果左上角需要画圆角,画出一个弧线出来。
     if  (cornerMask  &  UIImageRoundedCornerTopLeft) {
        
        
// 已左上的正方形的右下脚为圆心,半径为radius, 180度到90度画一个弧线,
        CGContextAddArc(context, rect.origin.x  +  radius, rect.origin.y  +  rect.size.height  -  radius,
                        radius, M_PI, M_PI 
/   2 1 );
    }
   
    
else  {
         
// 如果不需要画左上角的弧度。从线2终点,画到线3的终点,
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y  +  rect.size.height);
        
        
// 线3终点,画到线4的起点
        CGContextAddLineToPoint(context, rect.origin.x  +  radius, rect.origin.y  +  rect.size.height);
    }
    
    
// 画线4的起始,到线4的终点
    CGContextAddLineToPoint(context, rect.origin.x  +  rect.size.width  -  radius,
                            rect.origin.y 
+  rect.size.height);

    
// 画右上角
     if  (cornerMask  &  UIImageRoundedCornerTopRight) {
        CGContextAddArc(context, rect.origin.x 
+  rect.size.width  -  radius,
                        rect.origin.y 
+  rect.size.height  -  radius, radius, M_PI  /   2 0.0f 1 );
    }
    
else  {
        CGContextAddLineToPoint(context, rect.origin.x 
+  rect.size.width, rect.origin.y  +  rect.size.height);
        CGContextAddLineToPoint(context, rect.origin.x 
+  rect.size.width, rect.origin.y  +  rect.size.height  -  radius);
    }

    CGContextAddLineToPoint(context, rect.origin.x 
+  rect.size.width, rect.origin.y  +  radius);

    
// 画右下角弧线
     if  (cornerMask  &  UIImageRoundedCornerBottomRight) {
        CGContextAddArc(context, rect.origin.x 
+  rect.size.width  -  radius, rect.origin.y  +  radius,
                        radius, 
0.0f - M_PI  /   2 1 );
    }
    
else  {
        CGContextAddLineToPoint(context, rect.origin.x 
+  rect.size.width, rect.origin.y);
        CGContextAddLineToPoint(context, rect.origin.x 
+  rect.size.width  -  radius, rect.origin.y);
    }

    CGContextAddLineToPoint(context, rect.origin.x 
+  radius, rect.origin.y);

    
// 画左下角弧线
     if  (cornerMask  &  UIImageRoundedCornerBottomLeft) {
        CGContextAddArc(context, rect.origin.x 
+  radius, rect.origin.y  +  radius, radius,
                        
- M_PI  /   2 , M_PI,  1 );
    }
    
else  {
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y);
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y 
+  radius);
    }

    CGContextClosePath(context);
}


@implementation UIImage (Utility)
-  (UIImage  * )roundedRectWith:( float )radius cornerMask:(UIImageRoundedCorner)cornerMask
{
    UIImageView 
* bkImageViewTmp  =  [[[UIImageView alloc] initWithImage:self] autorelease];

    
int  w  =  self.size.width;
    
int  h  =  self.size.height;

    CGColorSpaceRef colorSpace 
=  CGColorSpaceCreateDeviceRGB();
    CGContextRef context 
=  CGBitmapContextCreate(NULL, w, h,  8 4   *  w, colorSpace, kCGImageAlphaPremultipliedFirst);

    CGContextBeginPath(context);
    addRoundedRectToPath(context,bkImageViewTmp.frame, radius, cornerMask);
    CGContextClosePath(context);
    CGContextClip(context);

    CGContextDrawImage(context, CGRectMake(
0 0 , w, h), self.CGImage);

    CGImageRef imageMasked 
=  CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    UIImage    
* newImage  =  [UIImage imageWithCGImage:imageMasked];

    CGImageRelease(imageMasked);

    
return  newImage;
}

@end 

 

 实现方法如下:

-  (IBAction)showRectImage
{
    UIImage 
* rectImage  =  [UIImage imageNamed: @" test.jpg " ];
    self.imageView.image 
=  rectImage;
}

-  (IBAction)showRoundImage
{
    UIImage 
* rectImage  =  [UIImage imageNamed: @" test.jpg " ];
    UIImage 
* roundImage  =  [rectImage roundedRectWith: 100
                                          cornerMask:UIImageRoundedCornerBottomLeft
| UIImageRoundedCornerBottomRight | UIImageRoundedCornerTopLeft | UIImageRoundedCornerTopRight];
    self.imageView.image 
=  roundImage;
}


-  (IBAction)show2RoundImage
{
    UIImage 
* rectImage  =  [UIImage imageNamed: @" test.jpg " ];
    UIImage 
* round2Image  =  [rectImage roundedRectWith: 100
                                          cornerMask:UIImageRoundedCornerBottomLeft
| UIImageRoundedCornerBottomRight];
    self.imageView.image 
=  round2Image;

} 

 

对于四个角,用下面的角进行逻辑或的方法。

UIImageRoundedCornerTopRight
UIImageRoundedCornerTopLeft
UIImageRoundedCornerBottomRight

UIImageRoundedCornerBottomLeft 


+ (void)roundedImage:(UIImage *)image

          completion:(void (^)(UIImage *image))completion {

    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Begin a new image that will be the new image with the rounded corners

        // (here with the size of an UIImageView)

        UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);

        CGRect rect = CGRectMake(0, 0, image.size.width,image.size.height);

        

        // Add a clip before drawing anything, in the shape of an rounded rect

        [[UIBezierPath bezierPathWithRoundedRect:rect

                                    cornerRadius:image.size.width/2] addClip];

        // Draw your image

        [image drawInRect:rect];

        

        // Get the image, here setting the UIImageView image

        UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();

        

        // Lets forget about that we were drawing

        UIGraphicsEndImageContext();

        dispatch_async( dispatch_get_main_queue(), ^{

            if (completion) {

                completion(roundedImage);

            }

        });

    });

}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值