一、上下文变换
由名思意,在绘图指南(一)中我们把上下文比喻成画布,我们可以对画布进行平移、旋转、缩放的操作,这些操作统称为上下文变换。
我们可以通过更改CTM(当前变换矩阵,Quartz通过CTM来映射坐标关系)来实现这些操作。Quartz 2D共提供了3个函数来直接修改CTM,分别是:
CGContextTranslateCTM
:对图形上下文做平移操作(基于原点)CGContextRotateCTM
:对图形上下文做旋转操作CGContextScaleCTM
:对图形上下文做缩放操作
在绘图指南(一)中提到CTM也是图形状态的一部分,所以在修改CTM前最好保存下初始状态,使用完就恢复原状态免得多次修改自己都搞不清基于什么样的坐标系绘图了。下面通过一张图片来描述上下文变换。
把
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 112 + 100, 213 + 100));
[image drawInRect:CGRectMake(0, 0, 112, 213)];
分别插入每个操作后
- (void)drawRect:(CGRect)rect {
[self transfromImage];
}
- (void) transfromImage{
UIImage * image = [UIImage imageNamed:@"Beauty3.png"];
//保存初始状态
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
//右移100,下移100
CGContextTranslateCTM(context, 100, 100);
//X轴缩放0.8,Y轴缩放0.5
CGContextScaleCTM(context, 0.8, 0.8);
//旋转45℃
CGContextRotateCTM(context, M_PI_4 / 4);
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 112 + 100, 213 + 100));
[image drawInRect:CGRectMake(0, 0, 112, 213)];
//恢复到初始状态
CGContextRestoreGState(context);
}
得到的效果图如下:



从上面三张图可以看出对CTM的操作改变的是整个图形上下文。
我们知道在UIKit框架中,我们可以操作UIView的
Transform
属性来控制控件的形变,在Quartz中我们也可以创建独一无二的变换矩阵,用CGContextConcatCTM
方法将此变换矩阵应用到CTM中,常用的仿射变换函数有以下几个,和上面的几个函数作用相同
CGAffineTransformMakeTranslation
:对图形上下文做平移操作(基于原点)CGAffineTransformTranslate
:将平移操作应用于当前的仿射变换CGAffineTransformMakeRotation
:对图形上下文做旋转操作CGAffineTransformRotate
:将旋转操作应用于当前的仿射变换CGAffineTransformMakeScale
:对图形上下文做缩放操作CGAffineTransformScale
:将缩放操作应用于当前的仿射变换
通过CGAffineTransform
操作上下文变换如下
- (void) transfromImage{
UIImage * image = [UIImage imageNamed:@"Beauty3.png"];
//保存初始状态
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
//右移100,下移100
CGAffineTransform moveTransfrom = CGAffineTransformMakeTranslation(100, 100);
//应用仿射变换到当前上下文的CTM
CGContextConcatCTM(context, moveTransfrom);
//X轴缩放0.8,Y轴缩放0.5
CGAffineTransform scaleTransfrom = CGAffineTransformMakeScale(0.8, 0.8);
//应用仿射变换到当前上下文的CTM
CGContextConcatCTM(context, scaleTransfrom);
//旋转45℃
CGAffineTransform rotateTransfrom = CGAffineTransformMakeRotation(M_PI_4 / 4);
// CGAffineTransform rotateTransfrom = CGAffineTransformRotate(scaleTransfrom, M_PI_4 / 4);
//应用仿射变换到当前上下文的CTM
CGContextConcatCTM(context, rotateTransfrom);
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 112 + 100, 213 + 100));
[image drawInRect:CGRectMake(0, 0, 112, 213)];
//恢复到初始状态
CGContextRestoreGState(context);
}
和通过CGContext
操作上下文变换效果一样。我们也可以使用CGAffineTransformMake(<#CGFloat a#>, <#CGFloat b#>, <#CGFloat c#>, <#CGFloat d#>, <#CGFloat tx#>, <#CGFloat ty#>)
函数创建独一无二的仿射变换矩阵,你可以看到这个函数包含6个参数,它可以在3 x 3矩阵中对六个关键项进行仿射变换,下图显示了3 x 3变换矩阵的六个临界值a,b,c,d,tx和ty,我们可以看到第三列数值为0,0,1,是因为Quartz是2d绘图引擎,对上下文的操作理所当然也只能操作x与y轴,而不包含z轴:

当我们对一个点(x, y)进行上图的仿射变换时

其结果(x', y ')如下图所示:

如果你创建的新的矩阵为

那么其结果(x', y ')等于

该矩阵描述的是对(x, y)缩放的操作,关于矩阵更深的了解,请戳官方文档
二、模式
未完待续
网友评论