前言:Quartz默认采用设备无关的user space来进行绘图,当context(画板)建立之后,默认的坐标系原点以及方向也就确认了,可以通过CTM(current transformation matrix)来修坐标系的原点。从数组图像处理的角度来说,就是对当前context state乘以一个状态矩阵。其中的矩阵运算开发者可以不了解
最初的状态和代码
#import "CustomView.h" @implementation CustomView - (void)drawRect:(CGRect)rect { [super drawRect:rect]; //画一个矩形 CGContextRef context = UIGraphicsGetCurrentContext(); CGContextAddRect(context, CGRectMake(10,10,40, 20)); CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor); CGContextFillPath(context); } -(instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { self.opaque = NO; self.layer.borderColor = [UIColor lightGrayColor].CGColor; self.layer.borderWidth = 1.0; } return self; } @end
在控制器里调用一下就可以了
CustomView * customView = [[CustomView alloc] initWithFrame:CGRectMake(100, 100,100, 100)]; [self.view addSubview:customView];
图解
Translate
假如我们在绘制前,进行坐标系移动会是什么效果呢?
代码:
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; //画一个矩形 CGContextRef context = UIGraphicsGetCurrentContext(); //移动坐标系 CGContextTranslateCTM(context, 10, 10); CGContextAddRect(context, CGRectMake(10,10,40, 20)); CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor); CGContextFillPath(context); }
效果:
代码中 我们还是在(10,10)点绘制,但是要注意,当前坐标系的原点已经移动到(10,10)了。
Rotate
在Transform的基础上 我们再Rotate 45度,注意CGContextRotateCTM传入的参数是弧度
代码
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; //画一个矩形 CGContextRef context = UIGraphicsGetCurrentContext(); //移动坐标系 CGContextTranslateCTM(context, 10, 10); //旋转坐标系 CGContextRotateCTM(context, M_PI_4); CGContextAddRect(context, CGRectMake(10,10,40, 20)); CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor); CGContextFillPath(context); }
效果
Scale
对于Scale相对来说,好理解一些,无非就是成比例放大或缩小
代码
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; //画一个矩形 CGContextRef context = UIGraphicsGetCurrentContext(); //移动坐标系 CGContextTranslateCTM(context, 10, 10); //旋转坐标系 CGContextRotateCTM(context, M_PI_4); //缩放坐标系 CGContextScaleCTM(context, 0.5, 0.5); CGContextAddRect(context, CGRectMake(10,10,40, 20)); CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor); CGContextFillPath(context); }
效果
状态保存 恢复
在复杂的绘制图中,我们可能指向对一个subPath进行缩放移动旋转。这个时候,状态堆栈就起到作用了。
代码
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; //画一个矩形 CGContextRef context = UIGraphicsGetCurrentContext(); //保存状态 入栈 CGContextSaveGState(context); //移动坐标系 CGContextTranslateCTM(context, 10, 10); //旋转坐标系 CGContextRotateCTM(context, M_PI_4); //缩放坐标系 CGContextScaleCTM(context, 0.5, 0.5); CGContextAddRect(context, CGRectMake(20,20,40, 20)); CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor); CGContextFillPath(context); //推出栈顶部状态 CGContextRestoreGState(context); //这里坐标系已经回到了最开始的状态 CGContextAddRect(context, CGRectMake(0, 0, 20, 20)); CGContextFillPath(context); }
效果
Affine Transforms
可以通过以下方法先创建放射矩阵,然后在把放射矩阵映射到CTM
CGAffineTransform
CGAffineTransformTranslate
CGAffineTransformMakeRotation
CGAffineTransformRotate
CGAffineTransformMakeScale
CGAffineTransformScale
时间: 2024-10-26 02:52:53