CGAffineTransform 图像处理类

CGAffineTransform 介绍

概述

CGAffineTransform是一个用于处理形变的类,其可以改变控件的平移、缩放、旋转等,其坐标系统采用的是二维坐标系,即向右为x轴正方向,向下为y轴正方向

在UIView中有一个transform属性便是专门用来控制形变的,其使用方法如下

样例素材

在介绍UIView形变的过程中,我们会使用一个UIImageView图片为例,对各动画效果进行演示

@property (nonatomic, strong) UIImageView *demoImageView;

- (void)viewDidLoad
{
[super viewDidLoad];

self.demoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, [[UIScreen mainScreen] bounds].size.width-40, [[UIScreen mainScreen] bounds].size.height-40)];
self.demoImageView.image = [UIImage imageNamed:@"demo"];
[self.view addSubview:self.demoImageView];
}

方法介绍

CGAffineTransformMakeTranslation
实现以初始位置为基准,在x轴方向上平移x单位,在y轴方向上平移y单位

// 格式
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
// 样例
self.demoImageView.transform = CGAffineTransformMakeTranslation(100, 100);

注: 当tx为正值时,会向x轴正方向平移,反之,则向x轴负方向平移;当ty为正值时,会向y轴正方向平移,反之,则向y轴负方向平移

CGAffineTransformMakeScale
实现以初始位置为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍
// 格式
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
// 样例
self.demoImageView.transform = CGAffineTransformMakeScale(2, 0.5);

注: 当sx为正值时,会在x轴方向上缩放x倍,反之,则在缩放的基础上沿着竖直线翻转;当sy为正值时,会在y轴方向上缩放y倍,反之,则在缩放的基础上沿着水平线翻转

CGAffineTransformMakeRotation
实现以初始位置为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)

// 格式
CGAffineTransformMakeRotation(CGFloat angle)
// 样例
self.demoImageView.transform = CGAffineTransformMakeRotation(M_PI*0.5);

注1: 当angle为正值时,逆时针旋转坐标系统,反之顺时针旋转坐标系统

注2: 逆时针旋转坐标系统的表现形式为对控件进行顺时针旋转

CGAffineTransformTranslate
实现以一个已经存在的形变为基准,在x轴方向上平移x单位,在y轴方向上平移y单位

// 格式
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
// 样例
CGAffineTransform transform = CGAffineTransformMakeTranslation(50, 50);
self.demoImageView.transform = CGAffineTransformTranslate(transform, 50, 50);

CGAffineTransformScale
实现以一个已经存在的形变为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍

// 格式
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
// 样例
CGAffineTransform transform = CGAffineTransformMakeScale(2, 0.5);
self.demoImageView.transform = CGAffineTransformScale(transform, 2, 1);

CGAffineTransformRotate
实现以一个已经存在的形变为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)

// 格式
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
// 样例
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI*0.25);
self.demoImageView.transform = CGAffineTransformRotate(transform, M_PI*0.25);

特殊地,transform属性默认值为CGAffineTransformIdentity,可以在形变之后设置该值以还原到最初状态

// 样例
self.demoImageView.transform = CGAffineTransformIdentity;

CGAffineTransform原理
CGAffineTransform形变是通过”仿射变换矩阵”来控制的,其中平移是矩阵相加,旋转与缩放则是矩阵相乘,为了合并矩阵运算中的加法和乘法,引入了齐次坐标的概念,它提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法.CGAffineTransform形变就是把二维形变使用一个三维矩阵来表示,其中第三列总是(0,0,1),形变通过前两列来控制,系统提供了CGAffineTransformMake结构体来控制形变

// 格式
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)

//移动效果
CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);

//旋转效果
CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle);
CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);

//缩放效果
CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);

//反转效果
CGAffineTransform CGAffineTransformInvert(CGAffineTransform t);

//只对局部产生效果
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);

//判断两个AffineTrans是否相等
bool CGAffineTransformEqualToTransform(CGAffineTransform t1, CGAffineTransform t2);

//获得Affine Transform
CGAffineTransform CGContextGetUserSpaceToDeviceSpaceTransform(CGContextRef c);

//下面的函数只起到查看的效果,比如看一下这个用户空间的点,转换到设备空间去坐标是多少

CGPoint CGContextConvertPointToDeviceSpace(CGContextRef c, CGPoint point);
CGPoint CGContextConvertPointToUserSpace(CGContextRef c, CGPoint point);
CGSize CGContextConvertSizeToDeviceSpace(CGContextRef c, CGSize size);
CGSize CGContextConvertSizeToUserSpace(CGContextRef c, CGSize size);
CGRect CGContextConvertRectToDeviceSpace(CGContextRef c, CGRect rect);
CGRect CGContextConvertRectToUserSpace(CGContextRef c, CGRect rect);

举例说明:
一.平移变换,当我实验平移时,将下面代码放在按钮点击方法中,第一个方法第一次点击有效,第二个是每次点击都会平移,第三个不会平移

//平移变换
imgview.transform=CGAffineTransformMakeTranslation(10, 10); //每次移动参照点都是初始点
imgview.transform=CGAffineTransformTranslate(imgview.transform, 20, 20);//平移参照第一个参数的点
imgview.transform=CGAffineTransformIdentity;//初始点
二、旋转
//旋转
imgview.transform=CGAffineTransformMakeRotation(M_PI/4);//旋转参照初始值 正数顺时针 负数逆时针
imgview.transform=CGAffineTransformRotate(imgview.transform, -M_PI/4);//旋转参照第一个参数的值
三、缩放
// 缩放
imgview.transform=CGAffineTransformScale(imgview.transform,0.8,0.8);//在第一个参数的基础上缩放 第二三参数1时为正常大小
imgview.transform=CGAffineTransformMakeScale(0.5,0.5);//在原视图的基础上缩放
四、翻转
//翻转
// CGAffineTransform DefaultAffineTransform =CGAffineTransformMake(1, 0, 0, 1, 0, 0);//默认
// imgview.transform=CGAffineTransformInvert(imgview.transform); //调用此行代码并不会产生翻转效果,因为恒等矩阵*恒等矩阵还是恒等矩阵,这样就没有变化
CGAffineTransform AffineTransform =CGAffineTransformMake(0, 1, 1, 1, 1, 0);
imgview.transform=CGAffineTransformInvert(AffineTransform);
五、合并
//合并 将两个仿射合并成一个仿射效果
// CGAffineTransform AffineTransform1 =CGAffineTransformMakeScale(0.5,0.5);
CGAffineTransform AffineTransform1=CGAffineTransformScale(imgview.transform,0.8,0.8);
CGAffineTransform AffineTransform2 =CGAffineTransformMakeRotation(M_PI/4);
CGAffineTransform AffineTransform3=CGAffineTransformConcat(AffineTransform1,AffineTransform2);
CGAffineTransform AffineTransform4 =CGAffineTransformMake(0, 1, 1, 1, 1, 0);
imgview.transform=CGAffineTransformConcat(AffineTransform3,AffineTransform4);
六、判断是否相同
CGAffineTransform DefaultAffineTransform =CGAffineTransformMake(1, 0, 0, 1, 0, 0);
CGAffineTransform DefaultAffineTransform1 =CGAffineTransformMake(1, 0, 0, 1, 0, 0);
// CGAffineTransform AffineTransform1 =CGAffineTransformMakeScale(0.5,0.5);
bool flag=CGAffineTransformEqualToTransform(DefaultAffineTransform, DefaultAffineTransform1);
NSLog(@"%d",flag);