码迷,mamicode.com
首页 > 移动开发 > 详细

iOS开发——图层OC篇&Quartz 2D各种绘制实例

时间:2015-08-06 00:18:54      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

Quartz 2D各种绘制实例

首先说一下,本篇文章只是介绍怎么使用Quartz 2D绘制一些常用的图像效果,关于Quartz和其他相关技术请查看笔者之前写的完整版(Quartz 2D详解

 

一:画线

 

 1     // 1.获取跟当前View相关联的layer上下文(画板)
 2     // 总结:目前获取的所有上下文都是以UIGraphics开头
 3     // CGContextRef:上下文类型
 4     // CG:CoreGraphics Ref:引用
 5     CGContextRef ctx = UIGraphicsGetCurrentContext();
 6     
 7     // 2.绘制内容,拼接路径
 8     // 创建贝瑟尔路径,因为里面已经封装好了很多路径
 9     UIBezierPath *path = [UIBezierPath bezierPath];
10     // 绘制一条直线
11     // 设置起点
12     [path moveToPoint:CGPointMake(50, 50)];
13     // 添加一根线到某个点
14     [path addLineToPoint:CGPointMake(200, 200)];
15     
16     // 3.把拼接好的路径添加到上下文(画板)
17     // UIBezierPath -> CGPath,直接.CGPath
18     CGContextAddPath(ctx, path.CGPath);
19     
20     // 4.渲染上下文,就把内容显示到view
21     // 只要跟上下文有关系的东西,都以CGContext开头
22     CGContextStrokePath(ctx);

 

如果你需要画多条线的话,同样使用上面的方法只是添加两个点(这里是指不连续的),但是只需要使用通一个路径就可以,在一起渲染到图层上下文中

 

二:绘制曲线

 1     // 绘制曲线
 2     // 1.获取上下文
 3     CGContextRef ctx = UIGraphicsGetCurrentContext();
 4     
 5     // 2.拼接路径
 6     UIBezierPath *path = [UIBezierPath bezierPath];
 7     
 8     // 设置起点
 9     [path moveToPoint:CGPointMake(10, 125)];
10     
11     // 描述曲线
12     [path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 240)];
13     
14     [path addLineToPoint:CGPointMake(10, 125)];
15     
16     // 3.添加路径到上下文
17     CGContextAddPath(ctx, path.CGPath);
18     
19     // 设置绘图状态,一定要再渲染之前
20     // 设置颜色
21     [[UIColor redColor] setStroke];
22     
23     // 设置线段的宽度
24     CGContextSetLineWidth(ctx, 15);
25     // 设置线段的顶角样式
26     CGContextSetLineCap(ctx, kCGLineCapRound);
27     
28     // 设置连接样式
29     CGContextSetLineJoin(ctx, kCGLineJoinRound);
30     
31     // 4.渲染上下文
32     CGContextStrokePath(ctx);

 

三:绘制矩形

 1         // 创建路径
 2         UIBezierPath *path = [UIBezierPath bezierPath];
 3     
 4         // 拼接路径
 5         [path moveToPoint:CGPointMake(50, 50)];
 6     
 7         [path addLineToPoint:CGPointMake(200, 200)];
 8     
 9         // 画线
10         [path stroke];
11     
12         //     描述一个矩形
13        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10, 10, 200, 200) cornerRadius:100];
14     
15         [path stroke];
16     /********************************************************************/
17     UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 200, 100)];
18     
19     [path stroke];

 

四:绘制扇形

 1   
 2     
 3     // 1.获取上下文
 4     CGContextRef ctx = UIGraphicsGetCurrentContext();
 5     
 6     // 2.拼接路径
 7     CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
 8     // 画扇形
 9     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
10     
11     [path addLineToPoint:center];
12     
13     [path closePath];
14     
15     // 3.把路径添加到上下文
16     CGContextAddPath(ctx, path.CGPath);
17     
18     // 设置绘图的状态
19     [[UIColor redColor] setFill];
20     
21     [[UIColor greenColor] setStroke];
22     
23     CGContextSetLineWidth(ctx, 5);
24     
25     // 4.渲染上下文
26     CGContextDrawPath(ctx, kCGPathFillStroke);

 

五:画圆弧

 1     
 2     // 画圆弧
 3     // Center圆心
 4     // radius:半径
 5     // startAngle起始角度
 6     // endAngle:结束角度
 7     // clockwise:Yes 顺时针 No逆时针
 8     CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
 9     //    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:NO];
10     //
11     //    [path stroke];
12     
13     
14     // 画扇形
15     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
16     
17     [path addLineToPoint:center];
18     
19     //    [path addLineToPoint:CGPointMake(self.bounds.size.height * 0.5 + 100, self.bounds.size.height * 0.5)];
20     // 关闭路径:从路径的终点连接到起点
21     //    [path closePath];
22     // 设置填充颜色
23     [[UIColor redColor] setFill];
24     
25     // 设置描边颜色
26     [[UIColor greenColor] setStroke];
27     
28     //    [path stroke];
29     // 如果路径不是封闭的,默认会关闭路径
30     [path fill];

有的时候我们可能需要自己实现一个指示器(进度条),那么这个时候Quartz 2D就能很简单的实现了

1     CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.width * 0.5);
2     CGFloat radius = self.bounds.size.width * 0.5 - 2;
3     CGFloat startA = -M_PI_2;
4     CGFloat endA = -M_PI_2 + _progress * M_PI * 2;
5     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
6     
7     [path stroke];

 

六:绘制饼图

 1   // Drawing code
 2     
 3     NSArray *data = @[@25,@25,@20,@30];
 4     
 5     
 6     CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
 7     CGFloat radius = self.bounds.size.width * 0.5;
 8     CGFloat startA = 0;
 9     CGFloat endA = 0;
10     CGFloat angle = 0;
11     
12     for (NSNumber *num in data) {
13         // 画一个扇形
14         startA = endA;
15         angle = [num intValue] / 100.0 * M_PI * 2;
16         endA = startA + angle;
17         
18        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
19         
20         [path addLineToPoint:center];
21         
22         // set:同时设置描边和填充颜色
23         [[self randomColor] set];
24         
25         [path fill];
26         
27     }

 

七:绘制文字

 1     NSString *str = @"hello!";
 2     
 3     // Attributes:属性
 4     // 给一个字符串添加属性,可以叫富文本,颜色,字体大小,空心,阴影
 5     
 6     // 利用这个属性字典给文本添加属性
 7     NSMutableDictionary *strAttr = [NSMutableDictionary dictionary];
 8     // key,value
 9     // 如何找到设置文本的属性key
10     // 描述了字体
11     strAttr[NSFontAttributeName] = [UIFont boldSystemFontOfSize:50];
12     
13     // 设置描边的颜色和宽度
14     strAttr[NSStrokeWidthAttributeName] = @1;
15     
16     strAttr[NSStrokeColorAttributeName] = [UIColor redColor];
17     
18     NSShadow *shadow = [[NSShadow alloc] init];
19     
20     shadow.shadowColor = [UIColor yellowColor];
21     
22     shadow.shadowOffset = CGSizeMake(10, 10);
23     
24     shadow.shadowBlurRadius = 5;
25     
26     // 阴影
27     strAttr[NSShadowAttributeName] = shadow;
28     
29     // 文字颜色
30     strAttr[NSForegroundColorAttributeName] = [UIColor redColor];
31     
32     [str drawAtPoint:CGPointZero withAttributes:strAttr];

这里使用到了文字属性,但是他使用很简单,后面会介绍道关于图文混排在详细介绍他。

注意这两个方法

1     
2     // 会自动换行
3    [str drawInRect:rect withAttributes:nil];
4     
5     //不自动换行
6    [str drawAtPoint:CGPointZero withAttributes:nil];

 

八:绘制图片

 1     
 2     // UIKit框架封装的方法绘制内容
 3     
 4     // 裁剪,rect裁剪的区域
 5     
 6     
 7     // 文字和图片
 8     UIImage *image = [UIImage imageNamed:@"001"];
 9     
10     // 绘制的内容跟图片一样大
11 //    [image drawAtPoint:CGPointZero];
12     
13     // 裁剪注意点:一定要放在绘图之前
14     // 超出裁剪区域的内容会被裁剪掉
15     UIRectClip(CGRectMake(0, 0, 50, 50));
16     
17     // 把绘制的内容控制到某个区域内
18 //    [image drawInRect:CGRectMake(0, 0, 100, 100)];
19     [image drawAsPatternInRect:rect];

 

自定义控件之模仿UIImageView

 1 - (instancetype)initWithImage:(UIImage *)image
 2 {
 3     if (self = [super init]) {
 4         _image = image;
 5         self.frame = CGRectMake(0, 0, image.size.width, image.size.height);
 6     }
 7     return self;
 8 }
 9 - (void)setImage:(UIImage *)image
10 {
11     _image = image;
12     [self setNeedsDisplay];
13 }
14 
15 // Only override drawRect: if you perform custom drawing.
16 // An empty implementation adversely affects performance during animation.
17 - (void)drawRect:(CGRect)rect {
18     // Drawing code
19     
20     [_image drawInRect:rect];
21 }

直接使用

    iCocosImageView *imageV = [[iCocosImageView alloc] initWithImage:[UIImage imageNamed:@"汽水"]];
    
    [self.view addSubview:imageV];

 

九:图文上下文栈,有的时候我们在绘制时可能需要保存对应的上下文,在后面再来使用(恢复)

1     // 保存当前上下文的默认状态
2     CGContextSaveGState(ctx);
3 
4     // 恢复下上下文状态
5     // 取出之前的保存的状态覆盖掉当前的状态
6     CGContextRestoreGState(ctx);

十:关于矩阵的操作:(矩阵是数学中的一个概念,抱歉我数学不好只能帮你这么多了,哈哈)

 1     // 矩阵操作:上下文可以做平移,旋转,缩放,开发中用的比较多是旋转.
 2     // 获取跟view相关联的上下文
 3     CGContextRef ctx = UIGraphicsGetCurrentContext();
 4     
 5     // 平移
 6     CGContextTranslateCTM(ctx, 150, 200);
 7     
 8     // 旋转
 9     CGContextRotateCTM(ctx, M_PI_4);
10 
11     // 缩放
12     CGContextScaleCTM(ctx, 0.5, 0.5);
13     
14     UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, -100, 100, 200)];
15     
16     [[UIColor redColor] set];
17     
18     [path fill];

 

十一:绘制水印图片-》输出一张带水印的图片

 1     // 给一张图片添加文字或者Logo,生成一张新的带有文字或者Logo图片
 2     
 3     
 4     // 绘制图片到位图上下文,然后再利用位图上下文生成一张新的图片
 5     
 6     
 7     // 加载图片
 8     UIImage *image = [UIImage imageNamed:@"小黄人"];
 9     
10     // 1.开启位图上下文
11     // size:上下文的尺寸
12     // opaque:不透明,总结:在上下文中一般都是设置不透明度,控件才是设置透明度
13     // scale: 0表示不缩放
14     UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
15     
16     // 绘制图片
17     [image drawAtPoint:CGPointZero];
18     
19     // 绘制文字
20     NSString *str = @"小码哥";
21     [str drawAtPoint:CGPointZero withAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]}];
22     
23     // 从上下文内容中生成一张图片
24     image = UIGraphicsGetImageFromCurrentImageContext();
25     
26     // 结束上下文
27     UIGraphicsEndImageContext();
28     
29     // 把图片写入到桌面
30     
31     // image -> NSData
32     // 把图片生成一个png格式的二进制数据
33     // png已经高清图片格式
34 //    NSData *data = UIImagePNGRepresentation(image);
35     // compressionQuality:图片质量
36     
37     NSData *data = UIImageJPEGRepresentation(image, 0.00001);
38     
39     [data writeToFile:@"/Users/xiaomage/Desktop/image.jpg" atomically:YES];

 

十二:图片裁剪:我定义一个UIImage的分类,实现讲一张图片变成一张圆形的图片

 1 + (instancetype)imageCirCleWithCircleColor:(UIColor *)color CircleBorder:(CGFloat)border name:(NSString *)imageName
 2 {
 3     // 裁剪带圆环的图片
 4     CGFloat borderWH = border;
 5     
 6     // 加载图片
 7     UIImage *image = [UIImage imageNamed:imageName];
 8     
 9     CGRect bigContextRect = CGRectMake(0, 0, image.size.width + 2 * borderWH, image.size.height + 2 * borderWH);
10     
11     // 1.开启位图上下文
12     UIGraphicsBeginImageContextWithOptions(bigContextRect.size, NO, 0);
13     
14     // 2.画大圆
15     UIBezierPath *bigCirclePath = [UIBezierPath bezierPathWithOvalInRect:bigContextRect];
16     
17     // 设置大圆颜色
18     [color set];
19     
20     [bigCirclePath fill];
21     
22     // 3.设置裁剪区域
23     // 3.1 先描述裁剪区域
24     UIBezierPath *clipPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderWH, borderWH, image.size.width, image.size.height)];
25     [clipPath addClip];
26     
27     // 4.绘制图片
28     [image drawAtPoint:CGPointMake(borderWH, borderWH)];
29     
30     // 5.从上下文内容中生成一张图片
31     image = UIGraphicsGetImageFromCurrentImageContext();
32     
33     // 6.结束上下文
34     UIGraphicsEndImageContext();
35     
36     return image;
37 }

 

十三:图片截屏

 1     // 1.开启位图上下文
 2     UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
 3     
 4     // 获取当前的位图上下文
 5    CGContextRef ctx =  UIGraphicsGetCurrentContext();
 6     
 7     // 2.往上下文中填充内容,把控制器的view的内容画上去,应该是把控制器view上的图层画到上下文上.
 8     // 获取控制器view的图层
 9     CALayer *layer = self.view.layer;
10     
11     // 把layer中内容渲染到上下文中,图层只能渲染,不能绘制
12 //    [layer renderInContext:ctx];
13     [layer drawInContext:ctx];
14     
15     // 3.从上下文中取出图片
16     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
17     
18     // 4.结束上下文
19     UIGraphicsEndImageContext();
20     
21     NSData *data = UIImagePNGRepresentation(image);
22     
23     [data writeToFile:@"/Users/xiaomage/Desktop/view.png" atomically:YES];

 

十四:图片截屏,是有手势,根据手指在屏幕上移动的距离形成对角线产生一个半透明的View,在截图对应View区域的图片

 1 // 获取下当前的触摸
 2     CGPoint curP = [sender locationInView:_imageView];
 3     if (sender.state == UIGestureRecognizerStateBegan) {
 4         // 记录下一开始的位置
 5         _oriP = curP;
 6     }
 7     
 8     // 计算下黑色蒙版的frame
 9     CGFloat w = curP.x - _oriP.x;
10     CGFloat h = curP.y - _oriP.y;
11     
12     self.cover.frame = CGRectMake(_oriP.x, _oriP.y, w, h);
13 
14     
15     if (sender.state == UIGestureRecognizerStateEnded) { // 手指抬起
16         
17         // 裁剪图片,生成一张新图片
18         
19         // 开启位图上下文
20         UIGraphicsBeginImageContextWithOptions(_imageView.bounds.size, NO, 0);
21         
22         // 设置裁剪区域
23         UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame];
24         [path addClip];
25         
26         
27         // 绘制图片
28         [_imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
29         
30         // 生成图片
31         UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
32         
33         // 关闭上下文
34         UIGraphicsEndImageContext();
35         
36         _imageView.image = image;
37         
38         [self.cover removeFromSuperview];
39         
40         
41     }

遮罩View

 1 - (UIView *)cover
 2 {
 3     if (_cover == nil) {
 4         UIView *view = [[UIView alloc] init];
 5         
 6         
 7         view.backgroundColor = [UIColor blackColor];
 8         view.alpha = 0.5;
 9         
10         _cover = view;
11         
12         [self.view addSubview:view];
13         
14     }
15     return _cover;
16 }

 

十五:图片擦除:重点Clear方法,当然还有一种方法就是使的对应的区域变成白色

 1     // 拖动的时候,擦除图片的某一部分
 2     
 3     // 获取手指的触摸点
 4    CGPoint curP = [sender locationInView:sender.view];
 5     
 6     // 计算擦除的frame
 7     CGFloat wh = 30;
 8     CGFloat x = curP.x - wh * 0.5;
 9     CGFloat y = curP.y - wh * 0.5;
10     
11     CGRect frame = CGRectMake(x, y, wh, wh);
12     
13     // 开启位图上下文
14     UIGraphicsBeginImageContextWithOptions(sender.view.bounds.size, NO, 0);
15     
16     // 获取当前的上下文
17     CGContextRef ctx = UIGraphicsGetCurrentContext();
18     
19     // 把控件上的内容渲染到上下文
20     [sender.view.layer renderInContext:ctx];
21     
22     // 清除上下文中某一部分的内容
23     CGContextClearRect(ctx, frame);
24     
25     // 生成一张新的图片
26     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
27     
28     // 关闭上下文
29     UIGraphicsEndImageContext();
30     
31     // 重新显示到UIImageView
32     UIImageView *imageV = (UIImageView *)sender.view;
33     
34     imageV.image = image;

 

十六:绘制柱状图

 1     NSArray *arr = @[@20,@30,@50];
 2     
 3     // 获取当前上下文
 4     CGContextRef ctx = UIGraphicsGetCurrentContext();
 5     
 6     // 先算出固定值的变量
 7     CGFloat viewW = rect.size.width;
 8     CGFloat viewH = rect.size.height;
 9     int count = arr.count;
10     CGFloat w = viewW / (2 * count - 1);
11     
12     // 不固定的变量,先定义出来,方便后面使用
13     CGFloat x = 0;
14     CGFloat h = 0;
15     CGFloat y = 0;
16     
17     for (int i = 0; i < count; i++) {
18         x = i * w * 2;
19         h = viewH * ([arr[i] integerValue] / 100.0);
20         y = viewH - h;
21         // 拼接路径
22         UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)];
23         
24         // 设置绘图状态
25         [[self randomColor] set];
26         
27         // 将路径添加到上下文
28         CGContextAddPath(ctx, path.CGPath);
29         
30         // 渲染
31         CGContextFillPath(ctx);
32 
33     }

随机颜色

 1     /* 颜色有两种常见的表现方式,一个是RGB RGBA
 2      RGB是24位颜色,RGBA是32位颜色
 3      R,G,B,A四个颜色通道各占8位
 4      8个二进制位的取值访问是0~255
 5      所以R,G,B,A,每个颜色通道的取值范围是0~255
 6      iOS中UIColor colorWith...这个方法传的是浮点型
 7      取值范围是0~1
 8      所以将0~255的整数值转为0~1的小数
 9      比如平时写的120,那就是120/255.0
10      
11      */
12     
13     CGFloat r = arc4random_uniform(256)/ 255.0;
14     CGFloat g = arc4random_uniform(256)/ 255.0;
15     CGFloat b = arc4random_uniform(256)/ 255.0;
16     return [UIColor colorWithRed:r green:g blue:b alpha:1.0];

这里关于颜色的介绍清查看笔者之前写的:UIColor深入研究

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

iOS开发——图层OC篇&Quartz 2D各种绘制实例

标签:

原文地址:http://www.cnblogs.com/iCocos/p/4706117.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!