iOS开发UI篇——Quartz2D的介绍
引子:
今天再浏览网页时发现,有的人在提问Quartz2D中的上下文到底是什么意思,尽管有各路大神耐心、细致、详细、准确的解答,提问者还是一头雾水,不知所云。
在这里我也借此想就另外一件事说说我的看法,经常在论坛上看见有些帖子说咱们国家的编程水平照美国不知道差出多少年,就连阿三哥咱们也不能望其项背(大神勿喷)。毋庸置疑,我国的编程水平确实离美国的水准还有一定的距离,究其原因,我想这跟语言有极大的关系。由于编程语言是以英语为基础的,且文档也是全英文的,即使有大神将文档翻译成汉语,我想受翻译者水平、语言环境等因素的影响,其还原文档内容的程度也绝对是有差异的。可以想象,如果编程语言是汉语的话,那么代码看起来还不就像是小学生作文吗!当然编程语言也不可能是汉语,开个玩笑,我想说的是我国程序员的瓶颈很大一部分就是语言。
说了这么多,好像有点偏离主题了,我真正想说的是编程语言中有些翻译实在是让人不知所云,比如这里所说的上下文
,什么鬼!从小到大在语文里用的上下文,怎么就跑到编程语言来了,什么意思!还有诸如UITableViewCell中的原型
cell等等。。。
一、从上下文说起
上下文通俗点理解就是草稿纸
,假如你给妹子写情书,我想不能一次成文吧,必定会在一张草稿纸上先斟酌一下言辞,练习一下笔体吧。我们这里所说的上下文的功能就相当于草稿纸。我们拿段简单的代码来说明一下。
//1.获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//2.创建路径
UIBezierPath *path=[UIBezierPath bezierPath];
//3.绘制路径
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(250, 250)];
//4.添加路径
CGContextAddPath(ctx, path.CGPath);
//5.渲染
CGContextDrawPath(ctx, kCGPathStroke);
第一步就是我们所说的获取上下文,相当于拿来一张草稿纸。二三四步就是在这张草稿纸上写情诗。第五步渲染就是把草稿纸上的情诗誊写到好看的信纸上。
二、Quartz2D都能做什么?
1. 裁剪图片
2. 涂鸦/画板
3. 手势解锁
4. 制作图表
5. 自定义View
三、图片上下文的使用
由于图形上下文(Layer)必须在drawRect方法中实现,而图片上下文(Bitmap)可以在任何类中使用,使用较多的是图片上下文,所以这里对图片上下文做重点介绍。
1. 图形上下文的使用步骤
1.开启图片上下文
2.获取当前上下文
3.绘制路径
4.渲染
5.获取当前山下文的图片
6.关闭上下文
注意
:这里有一个注意点,在使用图像上下文时,如果只开启上下文而不关闭上下文,则在使用静态分析时会提示内存未释放,造成内存泄露,所以必须有开有关。这里也再一次告诉我们ARC并不是万能的。
2. 图形上下文的使用实例
- 裁剪圆形头像
UIImage *image=[UIImage imageNamed:@"me"];
//1.开启图片上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
//2.获取图片上下文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//3.绘制路径,添加路径
CGPoint center=CGPointMake(image.size.width*0.5, image.size.height*0.5);
CGFloat radis=MIN(image.size.width, image.size.height)*0.5;
UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:center radius:radis startAngle:0 endAngle:M_PI*2 clockwise:1];
CGContextAddPath(ctx, path.CGPath);
//4.裁剪
CGContextClip(ctx);
//5.绘制图片到图片上下文
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//6.获取裁剪完毕的圆形头像
UIImage *clipImage=UIGraphicsGetImageFromCurrentImageContext();
//7.关闭上下文
UIGraphicsEndImageContext();
注意
:裁剪出的环形头像实际上是方形的,只是圆形之外的部分未显示,只要将参数opaque该为YES就能看到实际情况(见图一)。另外,如果源图片是长方形,且图形上下文与源图片大小相同,而要显示在正方形的UIImageView中,则会出现图形的变形(见图二)。
3. 制作带水印图片
UIImage *image=[UIImage imageNamed:@"示例"];
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
//绘制图片
[image drawInRect:self.view.bounds];
//绘制文字
NSString *str=@"示例";
[str drawAtPoint:CGPointZero withAttributes:@{NSForegroundColorAttributeName:[UIColor blueColor],NSFontAttributeName:[UIFont systemFontOfSize:20]}];
//绘制logo
UIImage *logoImage=[UIImage imageNamed:@"logo"];
[logoImage drawInRect:CGRectMake(self.view.bounds.size.width-10-logoImage.size.width, self.view.bounds.size.height-10-logoImage.size.height, logoImage.size.width, logoImage.size.height)];
//获取图片
UIImage *finalImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(finalImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);