iOS支持两套图形API框架:Core Graphics/QuartZ 2D 和OpenGL ES。本系列文章将向大家介绍这两套API框架
Core Graphics Framework/QuartZ 2D
Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析。
QuartZ 2D是苹果公司开发的一套API,它是Core Graphics Framework的一部分
OpenGL ES
OpenGL ES是跨平台的图形API,属于OpenGL的一个简化版本。OpenGL ES是应用程序编程接口,该接口描述了方法、结构、函数应具有的行为以及应该如何被使用的语义。
因为OpenGL ES只是定义了应用程序编程接口,具体如何去实现,需要开发者具有扎实计算机图形变换的扎实基础。
使用QuartZ 2D
使用原理
在iOS上,所有的绘制图形都发生在UIView对象的所表示的矩形区域内。如果您使用系统提供的视图,绘制工作会自动得到处理。然而,如果您定义自己的定制视图,则必须自行提供绘制代码。例如,咱们定一个类是继承于UIView,那么我们会发现有一个被注释掉的 drawRect 方法,如图:
如果我们不将这个注释方法打开,那么系统将会按照自己的逻辑绘制视图;倘若开发者需要自己定制视图,那么需要在 drawRect 方法里提供绘制代码。
什么时候会触发 `drawRect` 方法?
1. 该视图对象初始化的时候
2. 显式调用视图的setNeedsDisplay或者setNeedsDisplayInRect:方法。
开始绘制
基本绘制
123456789101112131415CGContextRef context = UIGraphicsGetCurrentContext();//获得图形上下文//两个函数是构建描绘路径CGContextMoveToPoint (context, 75, 10);CGContextAddLineToPoint (context, 10, 150);CGContextAddLineToPoint (context, 160, 150);//函数是闭合描绘路径CGContextClosePath(context);// And stroke the path[[UIColor blackColor] setStroke]; //设置描边的颜色//CGContextStrokePath(context);//闭合路径描边[[UIColor redColor] setFill]; //设置要填充颜色CGContextDrawPath(context, kCGPathFillStroke);//设置描绘路径方式//kCGPathFillStroke,kCGPathFill,kCGPathStroke贝塞尔曲线
1234567891011121314151617181920212223CGContextRef cgContext = UIGraphicsGetC urrentContext();//CGContextBeginPath(cgContext);CGContextMoveToPoint(cgContext, 333, 0);CGContextAddCurveToPoint(cgContext, 333, 0, 332, 26, 330, 26);CGContextAddCurveToPoint(cgContext, 330, 26, 299, 20, 299, 17);CGContextAddLineToPoint(cgContext, 296, 17);CGContextAddCurveToPoint(cgContext, 296, 17, 296, 19, 291, 19);CGContextAddLineToPoint(cgContext, 250, 19);CGContextAddCurveToPoint(cgContext, 250, 19, 241, 24, 238, 19);CGContextAddCurveToPoint(cgContext, 236, 20, 234, 24, 227, 24);CGContextAddCurveToPoint(cgContext, 220, 24, 217, 19, 216, 19);CGContextAddCurveToPoint(cgContext, 214, 20, 211, 22, 207, 20);CGContextAddCurveToPoint(cgContext, 207, 20, 187, 20, 182, 21);CGContextAddLineToPoint(cgContext, 100, 45);CGContextAddLineToPoint(cgContext, 97, 46);CGContextAddCurveToPoint(cgContext, 97, 46, 86, 71, 64, 72);CGContextAddCurveToPoint(cgContext, 42, 74, 26, 56, 23, 48);CGContextAddLineToPoint(cgContext, 9, 47);CGContextAddCurveToPoint(cgContext, 9, 47, 0, 31, 0, 0);CGContextStrokePath(cgContext);}
绘制文本
12345678NSString* imagePath = [[NSBundle mainBundle] pathForResource:@"dog" ofType:@"png"];UIImage* myImageObj = [[UIImage alloc] initWithContentsOfFile:imagePath];//[myImageObj drawAtPoint:CGPointMake(0, 0)];[myImageObj drawInRect:CGRectMake(0, 0, 320, 480)];NSString *s = @"我的小狗";[s drawAtPoint:CGPointMake(100, 0) withFont:[UIFont systemFontOfSize:34.0]];绘制图像
需要注意的是,在QuartZ 2D中遵循的是笛卡尔坐标系,因此绘制图形时需要转换坐标系
CGContextSaveGState
是将当前图形状态要入到图形堆栈。
CGContextDrawImage(context, touchRect, image)
在上下文中绘制图形。CGContextRestoreGState
回复当前图形状态。123456789NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];UIImage *img = [UIImage imageWithContentsOfFile:path];CGImageRef image = img.CGImage;CGContextRef context = UIGraphicsGetCurrentContext();CGContextSaveGState(context);CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);CGContextDrawImage(context, touchRect, image);CGContextRestoreGState(context);变换
变换(transformation)修改了图形上下文中绘制图形的方式。可以通过移动、旋转或缩放实现变换。
Quartz提供了多种形式的变换,其中主要:CTM(当前变换矩阵)变换和仿射(affine)变换。
CTM(current transformation matrix)变换,这种变换比较简单,函数有:
CGContextRotateCTM
,旋转坐标CGContextScaleCTM
,缩放坐标CGContextTranslateCTM
,移动原点
仿射变换
CGAffineMakeRotation
,创建旋转矩阵仿射对象CGAffineMakeScale
,创建缩放矩阵仿射对象CGAffineMakeTranslation
,创建移动矩阵仿射对象CGAffineTransformRotate
,旋转矩阵仿射对象CGAffineTransformScale
,缩放矩阵仿射对象CGAffineTransformTranslate
,移动矩阵仿射对象CGContextConcatCTM
,连接到CTM变换移动变换
1CGContextTranslateCTM (myContext, 100, 50)旋转变换
1234567static inline double radians (double degrees) {return degrees * M_PI/180;}CGContextRotateCTM (myContext, radians(–45));//从对象角度://在Quartz坐标下正数为逆时针旋转,负数为顺时针旋转。//在UIKit坐标下正数为顺时针旋转,负数为逆时针旋转。缩放变换
12CGContextScaleCTM (myContext, .5, .75);//从对象角度:所有x坐标缩小0.5,所有y坐标缩小0.75。
- CTM变换示例代码:12345678910NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];UIImage *img = [UIImage imageWithContentsOfFile:path];CGImageRef image = img.CGImage;CGContextRef context = UIGraphicsGetCurrentContext();CGContextSaveGState(context);CGContextRotateCTM(context, M_PI);CGContextTranslateCTM(context, -img.size.width, -img.size.height);CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);CGContextDrawImage(context, touchRect, image);CGContextRestoreGState(context);
- 仿射变换示例代码12345678910111213NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];UIImage *img = [UIImage imageWithContentsOfFile:path];CGImageRef image = img.CGImage;CGContextRef context = UIGraphicsGetCurrentContext();CGContextSaveGState(context);CGAffineTransform myAffine = CGAffineTransformMakeRotation(M_PI);myAffine = CGAffineTransformTranslate(myAffine, -img.size.width, -img.size.height);CGContextConcatCTM(context, myAffine);CGContextRotateCTM(context, M_PI);CGContextTranslateCTM(context, -img.size.width, -img.size.height);CGRect touchRect = CGRectMake(0, 0, img.size.width, img.size.height);CGContextDrawImage(context, touchRect, image);CGContextRestoreGState(context);