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

转载 2015年11月20日 23:16:19
在iOS开发中经常需要用到圆角图像。简单搜索一下就能找到很多创建圆角图像的实现代码。我在Stack Overflow上找到了一段代码,略微修改了一下,写了个简单的Category方法,可以用来创建圆角图像。代码如下:
 
/* 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 
/ 21);
    }
   
    
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 / 20.0f1);
    }
    
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 / 21);
    }
    
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, 84 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

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

    CGContextDrawImage(context, CGRectMake(
00, 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_asyncdispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT0), ^{

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

        // (here with the size of an UIImageView)

        UIGraphicsBeginImageContextWithOptions(image.sizeNO, image.scale);

        CGRect rect = CGRectMake(00, 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/2addClip];

        // 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_asyncdispatch_get_main_queue(), ^{

            if (completion) {

                completion(roundedImage);

            }

        });

    });

}


相关文章推荐

iOS-圆角设置性能优化

查阅了好些关于圆角性能优化的帖子,总结下记录下来. 首先: DSImageViewRound 使用方法 iOS图片高性能设置圆角一般我们在iOS开发的过程中设置圆角都是如下这样设置的。 avat...

[IOS] UIImage创建圆角图片

UI开发中, 很多时候需要用到圆角图片或者圆形t

【iOS沉思录】UIImage圆角矩形的‘离屏渲染’和‘当前屏幕渲染’实现方法

iOS中为view添加圆角效果有两种方式,一种基于“离屏渲染”(off-screen-renderring),直接设置view的layer层参数即可简单实现,也很常用,但性能较低;另一种则是编写底层图...

创建一个简单的圆角ImageView

需求:创建一个简单的圆角ImageView,使左上角,右上角的边缘变成圆角.public class CornerImageView extends ImageView { int radiu...

【iOS沉思录】UIImage圆角矩形的‘离屏渲染’和‘在屏渲染’实现方法

iOS中为view添加圆角效果有两种方式,一种基于“离屏渲染”(off-screen-renderring),直接设置view的layer层参数即可简单实现,也很常用,但性能较低;另一种则是编写底层图...

Android:一个很简单的扑克游戏(从项目资源创建图像)

string.xml 简单的扑克牌游戏 扑克牌 再来一次 恭喜您,猜对了,你该买彩票了! 很遗憾,猜错了,有志者事竟成,再来一次! 猜猜A是哪...

iOS-UIImage的创建和简单使用

UIKit中有一些类可以用来操纵单个图像,还有一个图像类可以用来显示图像。Apple还提供了一种特殊的导航控制器,用于从图像库中选择图像。 UIImage类对图像及其底层数据进行封装。它可以直接...

简单的自定义一个拥有圆角的Dialog

简单的自定义一个拥有圆角的Dialog现在越来越多的App都会使用到Dialog(对话框)这一个东东,在写Dialog的时候为什么总是不如人愿,展现给我们的又是不一样的呢? 就在最近公司项目里出现了...

Ribbon+Opencv 2.4--实现一个简单的Opencv图像处理小工具

放假路上几天加上在北京弄了三天FPGA,有一周没更新博客了,昨天终于回到家,今天学点东西写写博客吧,东西很简单不过也算假期之旅的不错开始啊     昨天看豆子的《Qt5学习之路2》的时候发现了一个叫R...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)