CoreGraphics(Quartz 2D) | 基礎(chǔ)概念篇:概覽椭员、圖形上下文车海、顏色與顏色空間

圖片發(fā)自簡(jiǎn)書(shū)App

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)欲险。

引用自:關(guān)于“再現(xiàn)意圖”(Rendering intent)

如果不顯式的指定再現(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)崇堰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市涩咖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌繁莹,老刑警劉巖檩互,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咨演,居然都是意外死亡闸昨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)饵较,“玉大人拍嵌,你說(shuō)我怎么就攤上這事⊙撸” “怎么了横辆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)茄猫。 經(jīng)常有香客問(wèn)我狈蚤,道長(zhǎng),這世上最難降的妖魔是什么划纽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任脆侮,我火速辦了婚禮,結(jié)果婚禮上勇劣,老公的妹妹穿的比我還像新娘靖避。我一直安慰自己,他們只是感情好比默,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布幻捏。 她就那樣靜靜地躺著,像睡著了一般退敦。 火紅的嫁衣襯著肌膚如雪粘咖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天侈百,我揣著相機(jī)與錄音瓮下,去河邊找鬼。 笑死钝域,一個(gè)胖子當(dāng)著我的面吹牛讽坏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播例证,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼路呜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了织咧?” 一聲冷哼從身側(cè)響起胀葱,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笙蒙,沒(méi)想到半個(gè)月后抵屿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捅位,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年轧葛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搂抒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尿扯,死狀恐怖求晶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衷笋,我是刑警寧澤芳杏,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站右莱,受9級(jí)特大地震影響蚜锨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜慢蜓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一亚再、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晨抡,春花似錦氛悬、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至调煎,卻和暖如春镜遣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背士袄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工悲关, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娄柳。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓寓辱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赤拒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秫筏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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