CoreGraphics是"藝名",學(xué)名是Quartz 2D,是二維圖形繪制引擎隘击,支持 iOS 和 OS X侍芝。
Quartz 2D的API使用簡(jiǎn)單,提供了很多強(qiáng)大的特性埋同,如:透明層州叠,基于路徑繪圖,離屏渲染凶赁,先進(jìn)的色彩管理咧栗,防鋸齒渲染,以及PDF文件的創(chuàng)建虱肄、展示和解析致板。
關(guān)于CG,工作用到的并不是非常多咏窿,但是作為開(kāi)發(fā)者們耳熟能詳?shù)目蚣苷寤颉⑵鋬?yōu)秀的特性,奈何不了手癢癢集嵌。一直關(guān)于CG限于閱讀博客萝挤、官文(官方文檔)御毅,但“紙上得來(lái)終覺(jué)淺,絕知此事要躬行”啊怜珍。
此文是對(duì)于官文的總結(jié)和應(yīng)用亚享。
簡(jiǎn)介
哪些場(chǎng)景下會(huì)用到CoreGraphics
1.繪制圖形。
2.需要提供圖像編輯功能绘面。
3.創(chuàng)建或者展示bitmap圖片欺税。
4.與PDF相關(guān)的操作。
概覽
Page(畫(huà)布)
Quartz 2D在圖像中使用了繪畫(huà)者模型(painter’s model)揭璃。在繪畫(huà)者模型中晚凿,簡(jiǎn)單說(shuō),當(dāng)前的圖層A瘦馍,在上面添加圖層B歼秽,A被B遮蓋的地方將不會(huì)顯示出來(lái),而只顯示A未被覆蓋的地方和B層情组。
Page可以是一張紙(如果輸出設(shè)備是打印機(jī))燥筷,也可以是虛擬的紙張(如果輸出設(shè)備是PDF文件),還可以是bitmap圖像院崇。這根據(jù)實(shí)際使用的graphics context而定肆氓。
Graphics Context(圖形上下文)
Graphics Context 是一種不透明數(shù)據(jù)類型,它封裝了Quartz繪制圖像到輸出設(shè)備上所用到的信息底瓣,輸出設(shè)備可以是PDF文件谢揪,bitmap內(nèi)存或者顯示器。同一張圖片可以通過(guò)指定不同的Context捐凭,即可輸出到不同的設(shè)備上拨扶。
Quartz提供了以下幾種類型的Graphics Context,詳細(xì)的介紹將在后續(xù)章節(jié)說(shuō)明:
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Context
- Post Graphics Context
其他的圖形上下文
除了上面幾種Context茁肠,Quartz還提供下面這些上下文患民,他們都以CG開(kāi)頭,Quartz 2D在這些context上創(chuàng)建對(duì)象操作對(duì)象垦梆,從而獲得某一特定的輸出(大白話這么說(shuō)匹颤,根據(jù)你要?jiǎng)?chuàng)建的東西不一樣,可以是路徑奶赔、圖片惋嚎、layer等等,而創(chuàng)建不同的context站刑,從而輸出你要的結(jié)果另伍,比如一張美美的圖片啦)。
常用的
- CGPathRef:用于向量圖,可創(chuàng)建路徑摆尝,并進(jìn)行填充或描畫(huà)(stroke)
- CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩温艇。
- CGLayerRef:用于表示可用于重復(fù)繪制(如背景)和幕后(offscreen)繪制的繪畫(huà)層
- CGPatternRef:用于重繪圖
- CGShadingRef、CGGradientRef:用于繪制漸變
不常用的 詳細(xì)說(shuō)明鏈接
- CGFunctionRef; CGColorRef, CGColorSpaceRef; CGImageSourceRef,CGImageDestinationRef; CGFontRef; CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef; CGPDFStream, CGPDFStringRef, and CGPDFArrayRef;
CGPDFScannerRef, CGPDFContentStreamRef;
CGPSConverterRef;
Quartz 2D 坐標(biāo)系統(tǒng)
在iOS 3.2以后的版本堕汞,當(dāng)創(chuàng)建一個(gè)繪圖上下文時(shí)勺爱,UIKit對(duì)上下文進(jìn)行了額外的修改以匹配UIKit坐標(biāo)習(xí)慣。但讯检,patterns和shadows(不被CTM影響)單獨(dú)進(jìn)行調(diào)整以匹配UIKit坐標(biāo)系統(tǒng)琐鲁。因?yàn)樾枰斫庠谀姆N上下文中進(jìn)行繪制,并調(diào)整行為以匹配上下文的預(yù)期人灼。
內(nèi)存管理
通常围段,以”Create”或“Copy”單詞的函數(shù)獲取一個(gè)對(duì)象,當(dāng)使用完后必須釋放投放,否則將導(dǎo)致內(nèi)存泄露奈泪。如果不是用上面的兩種“關(guān)鍵字”定義的,你將不會(huì)擁有對(duì)象的引用灸芳,不需要釋放它涝桅。
如果你對(duì)一個(gè)對(duì)象沒(méi)有擁有權(quán)卻想要引用它,你必須retain它烙样,并在不需要的時(shí)候手動(dòng)釋放它冯遂,相應(yīng)的方法。
例如:創(chuàng)建了一個(gè)CGColorspace對(duì)象误阻,則使用函數(shù)CGColorSpaceRetain和CGColorSpaceRelease來(lái)retain和release對(duì)象债蜜。同樣,可以使用Core Foundation的CFRetain和CFRelease究反,但是注意不能傳遞NULL值給這些函數(shù)。
圖形上下文(Graphics Contexts)
獲取上下文的方式有:Quartz提供的創(chuàng)建函數(shù)儒洛、Mac OS X框架或IOS的UIKit框架提供的函數(shù)精耐。Quartz提供了多種Graphics Context的創(chuàng)建函數(shù),包括bitmap和PDF琅锻。
iOS卦停,在View Graphics Context繪制
在iOS應(yīng)用中,視圖顯示在屏幕上及它的內(nèi)容需要更新時(shí)會(huì)調(diào)用被調(diào)用drawRect:
方法恼蓬。你只需要實(shí)現(xiàn)drawRect:
方法惊完,并在其中獲取上下文(視圖對(duì)象會(huì)配置一個(gè)上下文給你),繪制你想要的圖像处硬。
調(diào)用UIGraphicsGetCurrentContext
獲取當(dāng)前的上下文小槐。
樣例代碼
CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1, 0, 0.5, 1); CGContextFillRect(context, CGRectMake (0, 0, 250, 150));
在Mac OS X中創(chuàng)建一個(gè)窗口Graphics Context
內(nèi)容不多,關(guān)于Mac開(kāi)發(fā),不多占用篇幅了凿跳,見(jiàn)參考文檔吧件豌。
創(chuàng)建 PDF Graphics Context
Quartz2D API 提供了兩個(gè)函數(shù)來(lái)創(chuàng)建 PDF Graphics Context。
CGPDFContextCreateWithURL控嗜。當(dāng)你需要用 Core Foundation URL 指定 PDF 輸出的位置時(shí)使用該函數(shù)茧彤。
CGPDFContextCreate 當(dāng)需要將pdf輸出發(fā)送給數(shù)據(jù)用戶時(shí)使用該方法。
創(chuàng)建 Bitmap Graphics Context
一個(gè)位圖Graphics Context接受一個(gè)指向內(nèi)存緩存(包含位圖存儲(chǔ)空間)的指針疆栏,當(dāng)我們繪制一個(gè)位圖Graphics Context時(shí)曾掂,該緩存被更新。在釋放Graphics Context后壁顶,我們將得到一個(gè)我們指定像素格式的全新的位圖遭殉。
注:位圖Graphics Context有時(shí)用于后臺(tái)繪制。CGLayer對(duì)象優(yōu)化了后臺(tái)繪制博助,因?yàn)镼uartz在顯卡上緩存了層险污。
UIGraphicsBeginImageContext([UIScreen mainScreen].bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1, 0.5, 0.5, 1);
CGContextFillRect(context, CGRectMake (0, 0, 100, 150));
->接下來(lái),獲取圖片
UIImage *imageOne = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
<->或者
CGImageRef myImage = CGBitmapContextCreateImage(context);
CGContextDrawImage(context, CGRectMake(0, 0, 300, 300), myImage);
char *bitmapData = CGBitmapContextGetData(context);
CGContextRelease (context);
if (bitmapData) free(bitmapData);
CGImageRelease(myImage);
支持的像素格式
位圖 Graphics Context支持的像素格式富岳,相關(guān)的顏色空間及像素格式支持的Mac OS X最早版本蛔糯。像素格式用bpp(每像素的位數(shù))和bpc(每個(gè)組件的位數(shù))來(lái)表示,詳細(xì)格式表格窖式。
iOS 共支持 8 種像素格式蚁飒。
- Null 8 bpp, 8 bpc, kCGImageAlphaOnly
- Gray 8 bpp, 8 bpc, kCGImageAlphaNone
- Gray 8 bpp, 8 bpc, kCGImageAlphaOnly
- RGB 16 bpp, 5 bpc, kCGImageAlphaNoneSkipFirst
- RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipFirst
- RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipLast
- RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedFirst
- RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedLast
反鋸齒
位圖 Graphics Context支持反鋸齒,當(dāng)位圖的分辯率明顯低于人眼的分辯率時(shí)就會(huì)產(chǎn)生鋸齒萝喘。使形狀看起來(lái)更平滑淮逻。
我們可以通過(guò)調(diào)用CGContextSetShouldAntialias來(lái)關(guān)閉位圖Graphics Context的反鋸齒效果。反鋸齒設(shè)置是圖形狀態(tài)的一部分阁簸。
可以調(diào)用函數(shù)CGContextSetAllowsAntialiasing來(lái)控制一個(gè)特定Graphics Context是否支持反鋸齒爬早;
CGContextRef context1 =UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context1, YES);
CGContextSetAllowsAntialiasing(context1, YES);
顏色與顏色空間
什么是顏色與顏色空間
Quartz中的顏色是用一組值來(lái)表示。而顏色空間用于解析這些顏色信息启妹。例如筛严,下表列出了在全亮度下藍(lán)色值在不同顏色空間下的值。如果不知道顏色空間及顏色空間所能接受的值饶米,我們沒(méi)有辦法知道一組值所表示的顏色桨啃。
Values(值) | Color Space(顏色空間) | Components(組件) |
---|---|---|
240 degrees 100% 100% | HSB | Hue, saturation, britness |
0, 0, 1 | RGB | Red, green, blue |
1, 1, 0, 0 | CMYK | Cyan ,magenta, yellow, black |
1, 0, 0 | BGR | Blue, green, red |
alpha值(透明度)
使用 CGContextSetAlpha(context, 0.2)
設(shè)置透明度。
使用 CGContextClearRect 清除上下文的 alpha
通道檬输。
創(chuàng)建設(shè)備依賴顏色空間
創(chuàng)建設(shè)備依賴灰度顏色空間照瘾。
CGColorSpaceCreateDeviceGray()
創(chuàng)建設(shè)備依賴RGB顏色空間。
CGColorSpaceCreateDeviceRGB()
創(chuàng)建設(shè)備依賴CMYK顏色空間丧慈。
CGColorSpaceCreateDeviceCMYK()
設(shè)置顏色空間析命。
CGContextSetFillColorSpace(context, colorSpace)
或 CGContextSetStrokeColorSpace(context, colorSpace)
樣例代碼:
//Device RGB. 設(shè)置設(shè)備依賴RGB顏色空間并設(shè)置顏色值。
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
//Device CMYK. 設(shè)置設(shè)備依賴CMYK顏色空間并設(shè)置顏色值。
CGContextSetCMYKStrokeColor(context, 1, 0, 0, 0, 1);
CGContextSetCMYKFillColor(context, 1, 0, 0, 0, 1);
//Device Gray.設(shè)置設(shè)備依賴灰度顏色空間并設(shè)置顏色值碳却。
CGContextSetGrayStrokeColor(context, 0.5, 1);
CGContextSetGrayFillColor(context, 0.5, 1);
//使用 CGColor 設(shè)置顏色值并使用 CGColor 指定的顏色空間队秩。
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat colors[4] = {1.0, 0.0, 0.0, 1.0};
CGColorRef color = CGColorCreate(colorSpace, colors);
CGContextSetStrokeColorWithColor(context, color);
CGContextSetFillColorWithColor(context, color);
調(diào)用如下函數(shù)來(lái)便捷的設(shè)置顏色值并使用正在使用的顏色空間。
CGContextSetStrokeColor(context, colors);
CGContextSetFillColor(context, colors);
設(shè)置和創(chuàng)建顏色
通過(guò)如下函數(shù)設(shè)置和創(chuàng)建顏色昼浦。
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor));
設(shè)置再現(xiàn)意圖(Rending Intent)
每個(gè)設(shè)備都有固定的可復(fù)制的顏色范圍(gamut)馍资,這是設(shè)備的物理性質(zhì)決定的。當(dāng)圖像從一個(gè)顏色空間向另一個(gè)顏色空間轉(zhuǎn)換時(shí)关噪,有些源設(shè)備顏色空間中呈現(xiàn)的顏色鸟蟹,不能在目標(biāo)設(shè)備顏色空間中復(fù)制出來(lái),這些不能復(fù)制的顏色叫色域外(out-of-gamut)顏色使兔。比如 RGB 顏色空間比 CMYK 的顏色空間要大建钥,有些在顯示器上能顯示的顏色不能在打印機(jī)上同樣打印出來(lái)。因?yàn)槲覀儾荒茉谀繕?biāo)設(shè)備顏色空間中復(fù)制出色域外顏色虐沥,我們必須用一些其他顏色來(lái)替代他們熊经。顏色空間轉(zhuǎn)換時(shí)顏色替換調(diào)整的規(guī)則就是再現(xiàn)意圖。你也可以查閱這里關(guān)于“再現(xiàn)意圖”(Rendering intent 和 Understanding rendering intents: Which one and why?
再現(xiàn)意圖用于指定如何將源顏色空間的顏色映射到圖形上下文的目標(biāo)顏色空間的顏色范圍內(nèi)欲险。
如果不顯式的指定再現(xiàn)意圖镐依,Quartz 使用“相對(duì)色度再現(xiàn)意圖”應(yīng)用于所有繪制(不包含位圖圖像)。
對(duì)于位圖圖像天试,Quartz默認(rèn)使用“感知再現(xiàn)意圖”槐壳。
調(diào)用 CGContextSetRenderingIntent(context, kCGRenderingIntentDefault)
來(lái)設(shè)置再現(xiàn)意圖。
再現(xiàn)意圖共有以下 5 種喜每。
typedef CF_ENUM (int32_t, CGColorRenderingIntent) {
kCGRenderingIntentDefault,//默認(rèn)
kCGRenderingIntentAbsoluteColorimetric,//絕對(duì)色度再現(xiàn)意圖
kCGRenderingIntentRelativeColorimetric,//相對(duì)色度再現(xiàn)意圖
kCGRenderingIntentPerceptual,//感知再現(xiàn)意圖
kCGRenderingIntentSaturation//飽和度再現(xiàn)意圖
};
詳細(xì)查看官文文檔 务唐。
這是CoreGraphic第一篇,基礎(chǔ)概念篇带兜,接下來(lái)會(huì)進(jìn)入實(shí)戰(zhàn)階段枫笛,如果你感興趣,來(lái)個(gè)?和關(guān)注鞋真。我們下期見(jiàn)崇堰。