簡記:
CGAffineTransformMake(a,b,c,d,tx,ty)
ad縮放bc旋轉(zhuǎn)tx,ty位移集灌,基礎(chǔ)的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);
為了把二維圖形的變化統(tǒng)一在一個坐標系里牧抵,引入了齊次坐標的概念,即把一個圖形用一個三維矩陣表示猬错,其中第三列總是(0,0,1),用來作為坐標系的標準茸歧。所以所有的變化都由前兩列完成倦炒。
以上參數(shù)在矩陣中的表示為:
|a??? b??? 0|
|c??? d??? 0|
|tx?? ty?? 1|
運算原理:原坐標設為(X,Y,1);
|a??? b??? 0|
[X,Y,? 1] ???? |c??? d??? 0|? ?? = ? ? [aX + cY +txbX + dY +ty1] ;
|tx ?? ty1|
通過矩陣運算后的坐標[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)進行平移鳖藕,其實這也就是函數(shù)
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的比例系數(shù)纵顾,其實這也就是函數(shù)
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] ;
可見,這個時候整葡,?就是旋轉(zhuǎn)的角度件余,逆時針為正,順時針為負遭居。其實這也就是函數(shù)
CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)的計算原理啼器。angle即?的弧度表示。
2.利用上面的變換寫一個UIImage矩陣變換的例子:
下面是一個關(guān)于image的矩陣運算的例子,無外乎是運用以上三種變換的組合俱萍,達到所定義的效果
//UIImageOrientation的定義端壳,定義了如下幾種變換
-(UIImage *)transformMake:(UIImage *)aImage{
//按照UIImageOrientation的定義,利用矩陣自定義實現(xiàn)對應的變換枪蘑;
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;
}