之前提过绘制图像首先需要取得图形上下文对象(CGContextRef),系统中维护一个CGContextRef的栈,在UI控件的drawRect方法调用前,系统会为当前绘图环境创建一个图形上下文对象并且置于CGContextRef栈顶,通过UIGraphicsGetCurrentContext()可以取得这个图像上下文对象。我们也可以创建自己的图像上下文对象,quartz 2d提供了相应的api给开发者创建各种上下文对象,当我们使用UIKit在IOS内存中绘图时,创建上下文的工作更加简单,只需要调用UIGraphicsBeginImageContextWithOptions即可创建一个基于内存绘图的上下文
- (void)drawRect:(CGRect)rect { //创建一个基于位图的上下文(context),并将其设置为当前上下文(context) //绘图区域大小 | 是否透明 | 缩放因子 //UIGraphicsBeginImageContextWithOptions(rect.size, YES, 1); //透明度默认YES 缩放因子1.0 UIGraphicsBeginImageContext(rect.size); //获取图像上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor magentaColor].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor); //绘制椭圆 CGContextStrokeRect(context, CGRectMake(20, 20, 100, 100)); //绘制矩形 CGContextFillEllipseInRect(context, CGRectMake(150, 20, 100, 100)); //绘制文字 [@"this is a jok" drawAtPoint:CGPointMake(20, 150) withAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Arial" size:30],NSForegroundColorAttributeName:[UIColor redColor]}]; //获取绘图上下文中的图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //结束绘图 UIGraphicsEndImageContext(); //将图片显示到界面上 [image drawInRect:rect]; //图片存储到沙盒中 NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"pic.png"]; NSLog(@"%@",path); [UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; }
从上例中我们可以看到,在内存中绘图的步骤和在view上绘图的步骤完全一样,内存中绘制完图片后也可以显示到视图上,或者存储到应用沙盒中,使用内存绘图的上下文,我们可以很方便的实现绘图板的功能
@implementation ZLTView { CGPoint _firstPoint; CGPoint _lastPoint; CGContextRef _imageContext; UIImage *_image; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { UIGraphicsBeginImageContext(self.frame.size); _imageContext = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(_imageContext, [UIColor purpleColor].CGColor); CGContextSetLineWidth(_imageContext, 5); } return self; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchPoint = [touch locationInView:self]; _firstPoint = touchPoint; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchPoint = [touch locationInView:self]; _lastPoint = touchPoint; CGContextMoveToPoint(_imageContext, _firstPoint.x, _firstPoint.y); CGContextAddLineToPoint(_imageContext, _lastPoint.x, _lastPoint.y); CGContextDrawPath(_imageContext, kCGPathStroke); _image = UIGraphicsGetImageFromCurrentImageContext(); [self setNeedsDisplay]; _firstPoint = _lastPoint; } - (void)drawRect:(CGRect)rect{ [_image drawInRect:rect]; }