您好,登錄后才能下訂單哦!
這篇文章主要介紹“iOS Transform坐標變化是什么”,在日常操作中,相信很多人在iOS Transform坐標變化是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”iOS Transform坐標變化是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在使用CGContext時,由于Quartz 2D與UIKit坐標不一致,所以需要對context進行再一次的變化,達到預期的效果。
1. 不同坐標原點介紹
在Quartz 2D中,坐標原點在畫布的左下角,而UIKit中,與屏幕坐標一致,以左上角為坐標原點。
如果以(0,0)點為原點繪制F,那么在不同的坐標系就會獲得如下的結果。 2. Quartz 2D與UIKit坐標系轉化
2.1 UIImage繪制
在iOS的UI開發中,以UIImage為例,繪制一張圖片,設置image的frame為(0, 0, 320, 320),會得到上圖右的畫面。
如果使用如下代碼讀取Context的transform,可以看到這個transform并不是單位矩陣。
CGRect frame = CGRectMake(0.0, 0.0, 720, 1280); UIGraphicsBeginImageContext(frame.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGAffineTransform contextTransform = CGContextGetCTM(context);;
這里的transform設置會使Quartz 2D與UIKit的坐標原點重合,也是方便了UIKit中控件的繪制,坐標系變化可以參考下圖。 這也是為什么如果直接在獲取到的context上調用CGContextDrawImage時會得到一個反轉的圖像的原因。
但如果使用UIImage的drawInRect方法,文檔是這么寫的: Instance Method draw(in:) Draws the entire image in the specified rectangle, scaling it as necessary to fit. Declaration func draw(in rect: CGRect) Parameters rect The rectangle (in the coordinate system of the graphics context) in which to draw the image. Discussion This method draws the entire image in the current graphics context, respecting the image’s orientation setting. In the default coordinate system, images are situated down and to the right of the origin of the specified rectangle. This method respects any transforms applied to the current graphics context, however. This method draws the image at full opacity using the CGBlendMode.normal blend mode.
也就是說,UIImage繪制時使用的坐標還是UIKit的內部坐標,所以并不需要對坐標系做任何變化,就可以繪制出與rect位置相同的圖片了,當然這個方法也會根據圖片的朝向繪制。
2.2 CGContextDrawImage繪制
在改變context的transform時,實際上在變化的其實是坐標系本身。
而調用繪制方法時,使用的還是坐標系內部坐標,所以當我們想基于獲取到的context繪制一個如UIKit顯示的圖片,我們還需要對繪制前的坐標系做調整。
//Y軸翻轉 CGContextScaleCTM(context, 1, -1);
//需要圖片原點與左上角對齊,還需Y軸向下平移圖片高度 CGContextTranslateCTM(context, 0, -imageSize.height);
//繪制圖片 CGContextDrawImage(context, frame, image.CGImage);
3 transform錨點變化
比如圖片編輯頁面,我們經常能碰到使用手勢對圖片進行縮放旋轉位移等變化,之后生成一張新的圖片。
根據不同的手勢回調,我們可以修改view.transform,使得界面上的view產生與手勢相應的變化。
在這里,UIKit為了方便我們修改UI界面,view的transform是以view的center為錨點的。
UIView的transform里面的描述是使用center來修改position。
Use this property to scale or rotate the view's frame rectangle within its superview's coordinate system. (To change the position of the view, modify the center property instead.) The default value of this property is CGAffineTransformIdentity.
而很多其他的方法在調用時,transform都需要以左上角為錨點,所以這里有需要做一次轉化,錨點影響如下圖。 在UI界面的修改中,我們可以使用縮放和旋轉手勢的回調值直接修改view的transform,以及位移的回調來修改center,便可以達到我們預期的效果。但這個transform無法使用在context的繪制上,因為坐標系的變化,是以原點為錨點來做的。
所以針對context現有坐標系的位置,錨點在左上角,需要進行一次transform的修改。
根據上圖也可以看出,錨點只會對位置信息產生影響,并不會改變縮放和旋轉。
UIImage *image; //初始化圖片
UIView *view;//應用變化的view,view的size跟image要一致保證縮放比例是對的。
CGAffineTransform transform = view.transform; CGSize imageSize = image.size; transform.tx = view.center.x; transform.ty = view.center.y; transform = CGAffineTransformTranslate(transform, -imageSize.width * 0.5, -imageSize.height * 0.5);
其中tx,ty為錨點在坐標系的位置
當前的錨點在視圖的中心點,我們需要改變到視圖的左上角,這樣就可以和坐標系原點重合。其中*(imageSize.width * 0.5, imageSize.height * 0.5)*為錨點在圖片中的位置,此時transform為錨點在視圖左上角時的變化矩陣。
4. 組合Transform
在CGContext上想得到上圖中間的結果,不僅需要應用縮小1/2和旋轉45度的變化,還需要調整。
之前說過CGContext應用旋轉是應用在坐標系上,跟視圖應用旋轉的方式是自身坐標系是一致的。所以當直接獲取到的CGContext,優化后的坐標系也是左上角為原點時,可以直接再CGContext上應用我們計算出的transform。
之后還是由于坐標系繪制是以自身坐標系計算,再做一輪坐標系的翻轉和位移來得到最后的結果,類似下圖的操作。
這里需要注意,每一次新的變化都是在之前變化的基礎上,所以無論是view還是對context的transform做修改都是有順序的,這一點與矩陣乘法一致,順序會影響結果。
到此,關于“iOS Transform坐標變化是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。