博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从UIImage的矩阵变换看矩阵运算的原理
阅读量:6176 次
发布时间:2019-06-21

本文共 4583 字,大约阅读时间需要 15 分钟。

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

 

[cpp] 
  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. }   

掌握矩阵运算的原理,对视图的矩阵操作便会得心应手,巧妙利用旋转,平移,缩放,组合起来达到你所想要的变换效果!

转载于:https://www.cnblogs.com/56ik/p/5135320.html

你可能感兴趣的文章
大话重构连载14:我们是这样自动化测试的
查看>>
我的友情链接
查看>>
iis6 php安装 (一)
查看>>
关于,在Mysql中,外键是否会影响性能的问题???
查看>>
利用javascript设置图片等比例缩小
查看>>
dedeCMS如何给频道页添加缩略图
查看>>
CoreSeek快速安装
查看>>
Linux 网络性能调试工具Netstat
查看>>
我的友情链接
查看>>
报表下载SSH
查看>>
我的友情链接
查看>>
Raid磁盘阵列真的是100%的安全吗?raid有哪些常见的故障?
查看>>
Raid5两块硬盘离线解决方案 -阵列数据恢复案例
查看>>
IBM AIX存储层结构介绍 / 常用命令整理
查看>>
sudo用法简记
查看>>
有关宏定义的一篇文章
查看>>
Kubernetes 基本概念
查看>>
Linux命令:ssh,scp使用及免密码登录
查看>>
我的友情链接
查看>>
在CentOS上编译安装Nginx+实验环境搭建+测试
查看>>