(是通過英文資料iOS Drawing扣扣巴巴一點點翻譯過來的筆記。應該會有不少不對的地方,諒解~)
圖形上下文(drawing context)是指在你的應用里有一個虛擬的畫布(canvas)用來繪圖。你可以通過“上下文”(雖然我也不清楚上下文是啥意思,就是context這個單詞的翻譯。。)來創建圖像,文件和自定義視圖,通過學習UIKit,Core Graphics和 Quartz里的基礎繪圖方法。
1.Framework框架
iOS的繪圖程序主要源于UIKit和QuartzCore Framework。QuartzCore Framework就是我們常說的,Quartz或者Quartz 2D。Quartz這個名字比蘋果內部貫徹的名字Core Graphics要出名的多,這本書(《iOS Drawing》)里提到的Quartz和Core Graphics都是同一個意思。大多以CG開頭的c語言API都是取自Core Graphics,
?通常我們說的框架有兩種:一是,UIKit繪圖框架;二是,Quartz;
????下面的章節會用特別多的例子來說明UIKit繪圖和Quartz繪圖的區別和聯系,如何交互使用等等,請特別注意。
?比如例子畫一個圓角矩形框
?通過UIKit
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:inset cornerRadius:12];
[bezierPath stroke];
?通過Quartz
CGContextFillEllipseInRect(context,rect);
2.When to Draw是什么時候使用呢?
1.創建自定義視圖;2.構建圖像;3.創建pdf文件;4.處理核心圖像
1.創建自定義視圖 creating custom views
本質上,每一個UIKit的視圖都是一個空的畫布。你可以完全自定義的畫出一個視圖。你只需要在一個特殊的方法drawRect:方法里繪制出來,這個方法允許你自定義視圖的樣子通過UIKit和Quartz里的繪圖方法。
2.構建圖像 building images
在iOS中,你一可以引入一個UIKit image內容或重新使用一個UIImage單例。它允許你創建一個新的圖像或者修改一個存在的圖像。Drawing允許你處理自定義圖像不依賴于已存在的庫或圖片文件。
3.創建pdf文件 creating PDFs
你可以繪制出一個UIKit pdf上下文,它既不直接出一個文件也不保存數據。它允許你處理來自app的pdf內容,分享,存儲,或者展示它們。
4.處理核心圖像 building with Core Graphics
你也許想一字節一字節地訪問圖片數據,這個需求用UIKit就不是很好完成,但是在Core Graphics的位圖上下文中便可以完美地處理。比如通過Core Graphics把RGB圖像轉換為灰度圖像。
3.上下文Contexts
每一個iOS繪圖操作都從一個context開始。從概念上說,上下文和一個空白頁或者一個空畫布相似。它們包括了所有繪圖中的狀態和信息。
在iOS中,最重要的圖形上下文有兩個:位圖(bitmap)上下文和PDF上下文。核心圖形庫還提供了第三個上下文的類型,它用來完成圖片處理任務而非用來繪圖。
1.位圖上下文 Bitmap Context
位圖上下文本質上是一個二維數組數據。這些數據的大小取決于每一個像素點的顏色類型代表著人什么。比如RGB圖,灰度圖等等。
2.PDF上下文 PDF Context
PDF很多地方和位圖上下文相似,它們通過相同的命令和方法來繪制,你設置顏色或者繪制形狀或文本就和繪制一個視圖或者圖像差不多。當然,他們也有不同的地方。
PDF以存有矢量數據。PDF上下文的內容也可能多于一頁,你需要創建邊界矩形來具體說明默認尺寸和每一頁PDF頁的位置。
3.核心圖像上下文 Core Image Contexts
Core Image framework可以讓你快速的處理圖像。有了它,你可以處理濾鏡,濾鏡鏈,實現特點捕捉(可以找到照片中的臉和眼睛),分析圖片使它自適應。
4.用UIKit創建一個上下文Establishing contexts in UIKit
1.創建一個位圖上下文
?注意所有方法等前綴,這里UI開頭,都是用的是UIKit的方法。
a.基礎位圖上下文
b.上下文選擇權許可允許以設備尺寸繪圖(我也不知道我翻譯的什么鬼。。。原文Context Opttions Enable Drawing at Device Scale)
鼓勵使用第二種方法創建位圖上下文。
2.創建PDF上下文
創建一個PDF上下文,你必須有一個文件路徑或者可變data對象,還需要提供一個邊界框,以及一個字典,用來具體說明元數據和安全信息。比如說,你想著名作者或者用戶密碼,文件權限等等。
5.用Quartz創建一個上下文。
?這一個例子的方法均用的CG開頭的方法,Core Graphics也就是Quartz的方法。
6.在上下文里繪圖 Drawing into Contexts
確切的說,使用Quartz的方法在上下文里繪圖。
1-5的內容是寫在1-4里面的~
7.在UIKit上下文里面繪圖 Drawing Within a UIKit Context
?這個例子的關鍵在UIGraphicsGetCurrentContext()通過UIKit的方法得到CG的context。
UIKit簡化了創建和管理上下文的方法,一句話就可以完成創建一個圖像上下文或者PDF上下文,看看跟1-4,1-5比起來是不是簡單多了?用UIGraphicsGetCurrentContext()方法就可以直接獲取到當前的圖像或者PDF上下文~
當然,在現在的UIKit里面還有更加先進的方法來完成繪制一個橢圓~~
同樣是畫了一個橢圓,卻沒有提到上下文context~是不是很神奇。(書里有一大段都是在描述沒有上下文很神奇,我就不翻譯了~)
發生了什么事情呢,事情是這樣的。UIKit擁有一個圖形上下文的堆棧,可以把繪圖操作放到棧頂的上下文去完成。這些設置,比如說灰色,也都會推倒棧頂的上下文里去。
那么問題來了,怎么才能讓核心繪圖上下文和UIKit融為一體呢?有兩個關鍵的方法就來了~
· 你可以手動推出一個上下文,通過UIGraphicsPushContext(context)方法。這個方法可以把上下文推到UIKit棧的頂端。
·你也可以調用UIGraphicsPopContext()。這個方法可以把堆棧頂端的上下文移除UIKit的上下文棧,激活堆棧的下一個上下文或者置空。
總結
總結來了~~
混合使用核心圖像上下文(Core Graphics context)和UIKit繪圖,有以下幾步:
1.創建一個核心繪圖上下文。
2.UIGraphicsPushContext(context)。
3.使用UIKit繪圖方法和Quartz的繪圖方法結合來完成繪圖。
4.(取回上下文的內容,得到一個image)
5.釋放上下文。
8.UIKit和Quartz的顏色
在iOS開發術語中有一個叫 toll free bridged(不用通行費就可以過橋。。。)的東西,什么意思呢,就是說很多核心庫里面的數據類型也可也通過交換在UIKit里面使用。比如說,ARC里面的__bridge。但是不幸的是,這個橋梁在Quartz和UIKit的關系里卻是缺席的,包括顏色。
在很多繪圖的類里面,UIKit通過Objective-C把Quartz的方法和Core Graphics里面的類包裝起來。比如UIColor里面包了個CGColor,UIBezierPath里面包了個CGPath,UIImage里面包了CGImage和CIImage。這些東西都不是等價的。雖然你可以很容易的訪問到背后的Quartz元素,但著并不能算是一個橋。
9.畫家模型 The Painter's Model
iOS用一個叫“畫家模型”的東西在上下文中繪圖。除非你特別說明,所有的畫都會畫在原有畫的上面。就像一個畫家物理繪圖是一樣的,
10.上下文狀態 Context State
setFill 方法用顏色來涂滿繪圖邊界線的內部。
setStroke 只是用來給繪圖邊界描一個邊。
如圖1-9.綠色是fill 。紫色是 stroke
通過CGContextSaveGState(context)和CGContextRestoreGState(context)可以實現保存之前的繪圖狀態。
代碼和效果圖如上。保存了之前第一次 繪圖 的狀態。
狀態類型~
一個上下文可以存儲很多種的狀態,不僅僅是fill和stroke。下面我們用一個表來看看吧~
t
加粗字體提醒自己回頭吧這個表翻譯成中文
為什么越寫到后面越來越卡,特別是倒入圖片之后。。寫著好累啊。。。還是把 drawing context這一章分開寫算了。。。
后面還有幾節,分別是
Context Coordinate System 上下文中的坐標系;
Clipping 剪輯;
Transforms 調整;
setting line parameters 線的參數設置;
總結;
然后第二章是 The Language of Geometry 幾何語言
Points Versus Pixels 點和像素;
View Coordinates 視圖坐標;
Key Structures 關鍵結構;
Using CGRectDivide() 使用前面這個方法;
Rectangle Utilities ?矩形工具;
Fitting and Filling 擬合和填充;
Summary總結。