zoukankan      html  css  js  c++  java
  • 从UIImage的矩阵变换看矩阵运算的原理

    转载:http://blog.csdn.net/likendsl/article/details/7595611

    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的矩阵运算的例子,无外乎是运用以上三种变换的组合,达到所定义的效果:

    1. //UIImageOrientation的定义,定义了如下几种变换  
    2. typedef enum   
    3. {  
    4.     UIImageOrientationUp,            // default orientation  
    5.   
    6.     UIImageOrientationDown,          // 180 deg rotation  
    7.   
    8.     UIImageOrientationLeft,          // 90 deg CCW  
    9.       
    10.     UIImageOrientationRight,         // 90 deg CW  
    11.       
    12.     UIImageOrientationUpMirrored,    // as above but image mirrored along other axis. horizontal flip  
    13.       
    14.     UIImageOrientationDownMirrored,  // horizontal flip  
    15.       
    16.     UIImageOrientationLeftMirrored,  // vertical flip  
    17.       
    18.     UIImageOrientationRightMirrored, // vertical flip  
    19.   
    20. } UIImageOrientation;  
    21.   
    22. //按照UIImageOrientation的定义,利用矩阵自定义实现对应的变换;  
    23.   
    24. -(UIImage *)transformImage:(UIImage *)aImage    
    25.   
    26. {    
    27.   
    28.     CGImageRef imgRef = aImage.CGImage;    
    29.       
    30.     CGFloat width = CGImageGetWidth(imgRef);    
    31.       
    32.     CGFloat height = CGImageGetHeight(imgRef);    
    33.        
    34.     CGAffineTransform transform = CGAffineTransformIdentity;    
    35.       
    36.     CGRect bounds = CGRectMake(0, 0, width, height);    
    37.          
    38.     CGFloat scaleRatio = 1;    
    39.          
    40.     CGFloat boundHeight;    
    41.       
    42.     UIImageOrientation orient = aImage.imageOrientation;    
    43.       
    44.     switch(UIImageOrientationLeftMirrored)    
    45.       
    46.     {    
    47.               
    48.         case UIImageOrientationUp:    
    49.               
    50.             transform = CGAffineTransformIdentity;  
    51.   
    52.             break;    
    53.                          
    54.         case UIImageOrientationUpMirrored:   
    55.               
    56.             transform = CGAffineTransformMakeTranslation(width, 0.0);    
    57.               
    58.             transform = CGAffineTransformScale(transform, -1.0, 1.0);    
    59.               
    60.             break;    
    61.                          
    62.         case UIImageOrientationDown:              
    63.             transform = CGAffineTransformMakeTranslation(width, height);    
    64.               
    65.             transform = CGAffineTransformRotate(transform, M_PI);    
    66.               
    67.             break;    
    68.                          
    69.         case UIImageOrientationDownMirrored:   
    70.               
    71.             transform = CGAffineTransformMakeTranslation(0.0, height);    
    72.               
    73.             transform = CGAffineTransformScale(transform, 1.0, -1.0);    
    74.               
    75.             break;    
    76.                         
    77.         case UIImageOrientationLeft:     
    78.               
    79.             boundHeight = bounds.size.height;    
    80.               
    81.             bounds.size.height = bounds.size.width;    
    82.               
    83.             bounds.size.width = boundHeight;    
    84.               
    85.             transform = CGAffineTransformMakeTranslation(0.0, width);    
    86.               
    87.             transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);    
    88.               
    89.             break;  
    90.                          
    91.         case UIImageOrientationLeftMirrored:     
    92.               
    93.             boundHeight = bounds.size.height;    
    94.               
    95.             bounds.size.height = bounds.size.width;    
    96.               
    97.             bounds.size.width = boundHeight;    
    98.               
    99.             transform = CGAffineTransformMakeTranslation(height, width);    
    100.               
    101.             transform = CGAffineTransformScale(transform, -1.0, 1.0);    
    102.               
    103.             transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);    
    104.               
    105.             break;    
    106.               
    107.         case UIImageOrientationRight: //EXIF = 8    
    108.               
    109.             boundHeight = bounds.size.height;    
    110.               
    111.             bounds.size.height = bounds.size.width;    
    112.               
    113.             bounds.size.width = boundHeight;    
    114.               
    115.             transform = CGAffineTransformMakeTranslation(height, 0.0);    
    116.               
    117.             transform = CGAffineTransformRotate(transform, M_PI / 2.0);    
    118.               
    119.             break;  
    120.                          
    121.         case UIImageOrientationRightMirrored:   
    122.               
    123.             boundHeight = bounds.size.height;    
    124.               
    125.             bounds.size.height = bounds.size.width;    
    126.               
    127.             bounds.size.width = boundHeight;    
    128.               
    129.             transform = CGAffineTransformMakeScale(-1.0, 1.0);    
    130.               
    131.             transform = CGAffineTransformRotate(transform, M_PI / 2.0);    
    132.               
    133.             break;    
    134.                                                                      
    135.         default:    
    136.               
    137.             [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];    
    138.               
    139.     }    
    140.        
    141.     UIGraphicsBeginImageContext(bounds.size);    
    142.              
    143.     CGContextRef context = UIGraphicsGetCurrentContext();    
    144.             
    145.     if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {    
    146.           
    147.         CGContextScaleCTM(context, -scaleRatio, scaleRatio);    
    148.           
    149.         CGContextTranslateCTM(context, -height, 0);    
    150.           
    151.     }    
    152.       
    153.     else {    
    154.           
    155.         CGContextScaleCTM(context, scaleRatio, -scaleRatio);    
    156.           
    157.         CGContextTranslateCTM(context, 0, -height);    
    158.           
    159.     }    
    160.          
    161.     CGContextConcatCTM(context, transform);    
    162.          
    163.     CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);    
    164.       
    165.     UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();  
    166.          
    167.     UIGraphicsEndImageContext();    
    168.          
    169.     return imageCopy;    
    170.       
    171. }   
    掌握矩阵运算的原理,对视图的矩阵操作便会得心应手,巧妙利用旋转,平移,缩放,组合起来达到你所想要的变换效果!


  • 相关阅读:
    Siege 3.0 正式版发布,压力测试工具
    Pomm 1.1.2 发布,专为 PG 设计的 ORM 框架
    Whonix 0.5.6 发布,匿名通用操作系统
    国内开源 java cms,Jspxcms 2.0 发布
    EZNamespaceExtensions.Net v2013增加对上下文菜单、缩略图、图标、属性表的支持
    GNU Guile 2.0.9 发布,Scheme 实现
    jdao 1.0.4 发布 轻量级的orm工具包
    OpenSearchServer 1.4 RC4 发布
    Percona Server for MySQL 5.5.3030.2
    Samba 4.0.5 发布
  • 原文地址:https://www.cnblogs.com/allanliu/p/4397836.html
Copyright © 2011-2022 走看看