iOS 集移动,旋转,缩放于一体的函数:CGAffineTransformMake(a,b,c,d,tx,ty)

简记:

CGAffineTransformMake(a,b,c,d,tx,ty) 

ad缩放bc旋转tx,ty位移,基础的2D矩阵

 公式

    x=ax+cy+tx
    y=bx+dy+ty

 

1.矩阵的基本知识:

struct CGAffineTransform

{
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

CGAffineTransform CGAffineTransformMake (CGFloat a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty);

为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准。所以所有的变化都由前两列完成。

以上参数在矩阵中的表示为:

 |a    b    0|

 |c    d    0|

 |tx   ty   1|

 

运算原理:原坐标设为(X,Y,1);

                            |a    b    0|

       [X,Y,  1]      |c    d    0|     =     [aX + cY + tx   bX + dY + ty  1] ;

                            |tx    ty  1|

通过矩阵运算后的坐标[aX + cY + tx   bX + dY + ty  1],我们对比一下可知:

第一种:设a=d=1, b=c=0.  

[aX + cY + tx   bX + dY + ty  1] = [X  + tx  Y + ty  1];

可见,这个时候,坐标是按照向量(tx,ty)进行平移,其实这也就是函数

CGAffineTransform CGAffineMakeTranslation(CGFloat tx,CGFloat ty)的计算原理。

第二种:设b=c=tx=ty=0.  

[aX + cY + tx   bX + dY + ty  1] = [aX    dY   1];

可见,这个时候,坐标X按照a进行缩放,Y按照d进行缩放,a,d就是X,Y的比例系数,其实这也就是函数

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)的计算原理。a对应于sx,d对应于sy。

第三种:设tx=ty=0,a=cosɵ,b=sinɵ,c=-sinɵ,d=cosɵ。

[aX + cY + tx   bX + dY + ty  1] = [Xcosɵ - Ysinɵ    Xsinɵ + Ycosɵ  1] ;

可见,这个时候,ɵ就是旋转的角度,逆时针为正,顺时针为负。其实这也就是函数

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)的计算原理。angle即ɵ的弧度表示。

2.利用上面的变换写一个UIImage矩阵变换的例子:

下面是一个关于image的矩阵运算的例子,无外乎是运用以上三种变换的组合,达到所定义的效果

//UIImageOrientation的定义,定义了如下几种变换
typedef enum 
{
    UIImageOrientationUp,            // default orientation

   UIImageOrientationDown,          // 180 deg rotation

   UIImageOrientationLeft,          // 90 deg CCW
    
    UIImageOrientationRight,         // 90 deg CW
    
    UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip
    
    UIImageOrientationDownMirrored,  // horizontal flip
    
    UIImageOrientationLeftMirrored,  // vertical flip
    
    UIImageOrientationRightMirrored, // vertical flip

} UIImageOrientation;

//按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;

-(UIImage *)transformImage:(UIImage *)aImage  

{  

    CGImageRef imgRef = aImage.CGImage;  
    
    CGFloat width = CGImageGetWidth(imgRef);  
    
    CGFloat height = CGImageGetHeight(imgRef);  
     
    CGAffineTransform transform = CGAffineTransformIdentity;  
    
    CGRect bounds = CGRectMake(0, 0, width, height);  
       
    CGFloat scaleRatio = 1;  
       
    CGFloat boundHeight;  
    
    UIImageOrientation orient = aImage.imageOrientation;  
    
    switch(UIImageOrientationLeftMirrored)  
    
    {  
            
        case UIImageOrientationUp:  
            
            transform = CGAffineTransformIdentity;

            break;  
                       
        case UIImageOrientationUpMirrored: 
            
            transform = CGAffineTransformMakeTranslation(width, 0.0);  
            
            transform = CGAffineTransformScale(transform, -1.0, 1.0); //沿y轴向左翻 
            
            break;  
                       
        case UIImageOrientationDown:            
            transform = CGAffineTransformMakeTranslation(width, height);  
            
            transform = CGAffineTransformRotate(transform, M_PI);  
            
            break;  
                       
        case UIImageOrientationDownMirrored: 
            
            transform = CGAffineTransformMakeTranslation(0.0, height);  
            
            transform = CGAffineTransformScale(transform, 1.0, -1.0);  
            
            break;  
                      
        case UIImageOrientationLeft:   
            
            boundHeight = bounds.size.height;  
            
            bounds.size.height = bounds.size.width;  
            
            bounds.size.width = boundHeight;  
            
            transform = CGAffineTransformMakeTranslation(0.0, width);  
            
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);  
            
            break;
                       
        case UIImageOrientationLeftMirrored:   
            
            boundHeight = bounds.size.height;  
            
            bounds.size.height = bounds.size.width;  
            
            bounds.size.width = boundHeight;  
            
            transform = CGAffineTransformMakeTranslation(height, width);  
            
            transform = CGAffineTransformScale(transform, -1.0, 1.0);  
            
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);  
            
            break;  
            
        case UIImageOrientationRight: //EXIF = 8  
            
            boundHeight = bounds.size.height;  
            
            bounds.size.height = bounds.size.width;  
            
            bounds.size.width = boundHeight;  
            
            transform = CGAffineTransformMakeTranslation(height, 0.0);  
            
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);  
            
            break;
                       
        case UIImageOrientationRightMirrored: 
            
            boundHeight = bounds.size.height;  
            
            bounds.size.height = bounds.size.width;  
            
            bounds.size.width = boundHeight;  
            
            transform = CGAffineTransformMakeScale(-1.0, 1.0);  
            
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);  
            
            break;  
                                                                   
        default:  
            
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];  
            
    }  
     
    UIGraphicsBeginImageContext(bounds.size);  
           
    CGContextRef context = UIGraphicsGetCurrentContext();  
          
    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {  
        
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);  
        
        CGContextTranslateCTM(context, -height, 0);  
        
    }  
    
    else {  
        
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);  
        
        CGContextTranslateCTM(context, 0, -height);  
        
    }  
       
    CGContextConcatCTM(context, transform);  
       
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);  
    
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
       
    UIGraphicsEndImageContext();  
       
    return imageCopy;  
    
} 

 

 

参考:

https://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值