CGAffineTransformMake(a,b,c,d,tx,ty) 矩陣運算的原理

簡記:

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;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末损谦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子岳颇,更是在濱河造成了極大的恐慌照捡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件话侧,死亡現(xiàn)場離奇詭異栗精,居然都是意外死亡,警方通過查閱死者的電腦和手機瞻鹏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門悲立,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人新博,你說我怎么就攤上這事薪夕。” “怎么了叭披?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵寥殖,是天一觀的道長。 經(jīng)常有香客問我涩蜘,道長嚼贡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任同诫,我火速辦了婚禮粤策,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘误窖。我一直安慰自己叮盘,他們只是感情好秩贰,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柔吼,像睡著了一般毒费。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上愈魏,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天觅玻,我揣著相機與錄音,去河邊找鬼培漏。 笑死溪厘,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的牌柄。 我是一名探鬼主播畸悬,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼珊佣!你這毒婦竟也來了蹋宦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤彩扔,失蹤者是張志新(化名)和其女友劉穎妆档,沒想到半個月后僻爽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虫碉,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年胸梆,在試婚紗的時候發(fā)現(xiàn)自己被綠了敦捧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡碰镜,死狀恐怖兢卵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绪颖,我是刑警寧澤秽荤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站柠横,受9級特大地震影響窃款,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牍氛,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一晨继、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搬俊,春花似錦紊扬、人聲如沸蜒茄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檀葛。三九已至,卻和暖如春腹缩,著一層夾襖步出監(jiān)牢的瞬間驻谆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工庆聘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胜臊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓伙判,卻偏偏與公主長得像象对,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宴抚,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容