- Quartz2D 編程指南(一)概覽管引、圖形上下文士败、路徑、顏色與顏色空間
- Quartz2D 編程指南(二)變換褥伴、圖案谅将、陰影
- Quartz2D 編程指南(三)漸變、透明層 重慢、數(shù)據(jù)管理
- Quartz2D 編程指南(四)位圖與圖像遮罩饥臂、CoreGraphics 繪制 Layer
- 概覽
- 圖形上下文
- 路徑
- 顏色與顏色空間
- 變換
- 圖案
- 陰影
- 漸變
- 透明層
- Quartz 2D 中的數(shù)據(jù)管理
- 位圖與圖像遮罩
- CoreGraphics 繪制 Layer
0.說明
本篇博客主要是對(duì)官方文檔的總結(jié)與補(bǔ)充。翻譯部分參考了南峰子的博客伤锚。你可以在參考資料中查看擅笔。
1.概覽
簡介
- Quartz2D 是二維圖形繪制引擎,支持 iOS 和 OS X屯援。
Page
- Quartz2D 在圖像中使用了繪畫者模型猛们。在繪畫者模型中,每個(gè)連續(xù)的繪制操作都是將一個(gè)繪制層放置于一個(gè)畫布狞洋,我們通常稱這個(gè)畫布為 Page弯淘。
Graphics Context
- Graphics Context 是一個(gè)數(shù)據(jù)類型(CGContextRef),用于封裝 Quartz 繪制圖像到輸出設(shè)備的信息吉懊。設(shè)備可以是PDF文件庐橙、bitmap或者顯示器的窗口。 CGContextRef 對(duì)應(yīng)繪畫者模式中的 Page借嗽。
- 當(dāng)用 Quartz 繪圖時(shí)态鳖,所有設(shè)備相關(guān)的特性都包含在我們所使用的Graphics Context 中。我們可以簡單地給 Quartz 繪圖序列指定不同的 Graphics Context恶导,就可將相同的圖像繪制到不同的設(shè)備上浆竭。
- Quartz提供了 5 種類型的 Graphics Context。Bitmap Graphics Context惨寿、PDF Graphics Context邦泄、Window Graphics Context、Layer Context裂垦、Post Graphics Context顺囊。
數(shù)據(jù)類型
- Quartz 2D 使用如下數(shù)據(jù)類型來創(chuàng)建對(duì)象,通過操作這些對(duì)象來獲取特定的圖形蕉拢。
- CGPathRef:用于向量圖特碳,可創(chuàng)建路徑诚亚,并進(jìn)行填充或描畫(stroke)
- CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩
- CGLayerRef:用于表示可用于重復(fù)繪制(如背景)和幕后 (offscreen)繪制的繪畫層
- CGPatternRef:用于重繪圖
- CGShadingRef、CGGradientRef:用于繪制漸變
- CGFunctionRef:用于定義回調(diào)函數(shù)测萎,該函數(shù)包含一個(gè)隨機(jī)的浮點(diǎn)值參數(shù)亡电。當(dāng)為陰影創(chuàng)建漸變時(shí)使用該類型
- CGColorRef, CGColorSpaceRef:用于告訴Quartz如何解釋顏色
- CGImageSourceRef,CGImageDestinationRef:用于在Quartz中移入移出數(shù)據(jù)
- CGFontRef:用于繪制文本
- *CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用于訪問PDF的元數(shù)據(jù)
- *CGPDFScannerRef, CGPDFContentStreamRef:用于解析PDF元數(shù)據(jù)
- *CGPSConverterRef:用于將PostScript轉(zhuǎn)化成PDF。在iOS中不能使用硅瞧。
圖形狀態(tài)
Quartz 通過修改當(dāng)前圖形狀態(tài)(current graphics state)來修改繪制操作的結(jié)果份乒。圖形狀態(tài)包含用于繪制程序的參數(shù)。繪制程序根據(jù)這些繪圖狀態(tài)來決定如何渲染結(jié)果腕唧。
可使用函數(shù)CGContextSaveGState來保存圖形狀態(tài)或辖,CGContextRestoreGState來還原圖形狀態(tài)。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextRestoreGState(context);
- 并不是當(dāng)前繪制環(huán)境的所有屬性都是圖形狀態(tài)的元素枣接。如颂暇,圖形狀態(tài)不包含當(dāng)前路徑(current path)。
坐標(biāo)系統(tǒng)
Quartz 的坐標(biāo)系與 UIKit 坐標(biāo)系 Y 軸相反但惶。
Quartz 通過使用當(dāng)前轉(zhuǎn)換矩陣(current transformation matrix耳鸯, CTM)將一個(gè)獨(dú)立的坐標(biāo)系統(tǒng)(user space)映射到輸出設(shè)備的坐標(biāo)系統(tǒng)(device space),以此來解決設(shè)備依賴問題膀曾。
使用 UIGraphicsBeginImageContextWithOptions 返回的繪圖上下文與UIKit 的坐標(biāo)系統(tǒng)相同县爬。
在 iOS 中,如果使用 UIImage 對(duì)象來包裹創(chuàng)建的 CGImage 對(duì)象添谊,可以不需要修改 CTM财喳。UIImage 將自動(dòng)進(jìn)行補(bǔ)償以適用 UIKit 的坐標(biāo)系統(tǒng)。
在 iOS 3.2 后斩狱,當(dāng) UIKit 為你的應(yīng)用程序創(chuàng)建一個(gè)繪圖上下文時(shí)耳高,也對(duì)上下文進(jìn)行了額外的修改以匹配 UIKit 的約定。
內(nèi)存管理
如果創(chuàng)建或拷貝一個(gè)對(duì)象所踊,你將擁有它泌枪,因此你必須釋放它。通常秕岛,如果使用含有”Create”或“Copy”單詞的函數(shù)獲取一個(gè)對(duì)象工闺,當(dāng)使用完后必須釋放,否則將導(dǎo)致內(nèi)存泄露瓣蛀。
如果使用不含有”Create”或“Copy”單詞的函數(shù)獲取一個(gè)對(duì)象,你將不會(huì)擁有對(duì)象的引用雷厂,不需要釋放它惋增。
如果你不擁有一個(gè)對(duì)象而打算保持它,則必須 retain 它并且在不需要時(shí) release 掉改鲫≌┟螅可以使用 Quartz2D 的函數(shù)來指定 retain 和 release 一個(gè)對(duì)象林束。例如,如果創(chuàng)建了一個(gè) CGColorspace 對(duì)象稽亏,則使用函數(shù) CGColorSpaceRetain 和 CGColorSpaceRelease 來 retain 和 release 對(duì)象壶冒。同樣,可以使用 Core Foundation 的 CFRetain 和 CFRelease截歉,但是注意不能傳遞 NULL 值給這些函數(shù)胖腾。
2.圖形上下文
簡介
- 我們可以通過兩種方式來獲取 Graphics Context:Quartz提供的創(chuàng)建函數(shù)、OS X 框架或 iOS 的 UIKit 框架提供的函數(shù)瘪松。
創(chuàng)建 Window Graphics Context
在 iOS 應(yīng)用程序中咸作,如果要在屏幕上進(jìn)行繪制,需要?jiǎng)?chuàng)建一個(gè) UIView 對(duì)象宵睦,并實(shí)現(xiàn)它的 drawRect: 方法记罚。
drawRect: 方法中視圖對(duì)象將為當(dāng)前的繪圖環(huán)境創(chuàng)建一個(gè) Graphics Context。我們可以通過調(diào)用 UIGraphicsGetCurrentContext 函數(shù)來獲取這個(gè) Graphics Context壳嚎。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
CGContextFillRect(context, CGRectMake (0, 0, 200, 100));
CGContextSetRGBFillColor(context, 0, 0, 1, .5);
CGContextFillRect(context, CGRectMake (0, 0, 100, 200));
*創(chuàng)建 PDF Graphics Context
Quartz2D API 提供了兩個(gè)函數(shù)來創(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
- iOS 中使用 UIGraphicsBeginImageContextWithOptions 取代 CGBitmapContextCreate 來創(chuàng)建 Bitmap Graphics Context 以便獲得相同的坐標(biāo)系。
UIGraphicsBeginImageContext([UIScreen mainScreen].bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
CGContextFillRect(context, CGRectMake (0, 0, 200, 100));
CGContextSetRGBFillColor(context, 0, 0, 1, .5);
CGContextFillRect(context, CGRectMake (0, 0, 100, 200));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();//CGBitmapContextCreateImage(context)
UIGraphicsEndImageContext();
像素格式
像素格式是在使用 CGBitmapContextCreate 創(chuàng)建 Bitmap Graphics Context 時(shí)需要指定的參數(shù)焙糟。
像素格式用 bpp(每像素的位數(shù))和 bpc(每個(gè)組件的位數(shù))來表示口渔。
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
抗鋸齒
我們可以通過調(diào)用 CGContextSetShouldAntialias 來關(guān)閉位圖Graphics Context的反鋸齒效果穿撮。反鋸齒設(shè)置是圖形狀態(tài)的一部分缺脉。
可以調(diào)用函數(shù)CGContextSetAllowsAntialiasing來控制一個(gè)特定Graphics Context是否支持反鋸齒;false表示不支持悦穿。該設(shè)置不是圖形狀態(tài)的一部分攻礼。當(dāng)上下文及圖形狀態(tài)設(shè)置為true時(shí),Quartz執(zhí)行反鋸齒栗柒。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShouldAntialias(context, YES);
CGContextSetAllowsAntialiasing(context, YES);
3.路徑
簡介
路徑定義了一個(gè)或多個(gè)形狀或者子路徑礁扮。一個(gè)子路徑可由直線,曲線瞬沦,或者同時(shí)由兩者構(gòu)成太伊。它可以是開放的,也可以是閉合的逛钻;可以是實(shí)線僚焦,可以是曲線;可以填充曙痘,也可以描邊等等芳悲。
路徑創(chuàng)建及路徑繪制是兩個(gè)獨(dú)立的工作立肘。首先我們創(chuàng)建路徑。當(dāng)我們需要渲染路徑時(shí)名扛,我們需要使用Quartz來繪制它谅年。
點(diǎn)
- 調(diào)用 CGContextMoveToPoint(context, 0, 0) 為新的子路徑指定起始點(diǎn)。
直線
調(diào)用 CGContextAddLineToPoint(context, 200, 200) 從起始點(diǎn)到指定點(diǎn)添加直線肮韧。
調(diào)用 CGContextAddLines(context, points, 3) 函數(shù)添加一系列相關(guān)的直線到子路徑中融蹂。
弧
調(diào)用 CGContextAddArc(context, 200, 200, 100, 0, M_PI_2, 0) 以指定圓心、半徑惹苗、起始/終止角度殿较、順/逆時(shí)針畫弧。
調(diào)用 CGContextAddArcToPoint(context, 200, 400, 400, 400, 100) 以當(dāng)前點(diǎn)與指定的兩個(gè)點(diǎn)連接的兩條直線為切線畫弧桩蓉。
曲線
調(diào)用 CGContextAddQuadCurveToPoint(context, 0, 100, 200, 100) 以一個(gè)控制點(diǎn)畫曲線淋纲。
調(diào)用 CGContextAddCurveToPoint(context, 100, 400, 200, 300, 100, 200) 以兩個(gè)控制點(diǎn)畫曲線。
閉合路徑
- 調(diào)用 CGContextClosePath(context) 閉合路徑院究。
橢圓
- 調(diào)用 CGContextAddEllipseInRect(context, CGRectMake(0, 0, 100, 200)) 畫橢圓洽瞬。
矩形
- 調(diào)用 CGContextAddRect(context, CGRectMake(200, 400, 100, 200)) 畫矩形。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 200, 200);
CGPoint point2 = CGPointMake(200, 200);
CGPoint point3 = CGPointMake(200, 400);
CGPoint point4 = CGPointMake(0, 200);
CGPoint points[3] = {point2, point3, point4};
CGContextAddLines(context, points, 3); // reset start point
CGContextAddArc(context, 200, 200, 100, 0, M_PI_2, 0);
CGContextAddArcToPoint(context, 200, 400, 400, 400, 100);
CGContextAddCurveToPoint(context, 100, 400, 200, 300, 100, 200);
CGContextAddQuadCurveToPoint(context, 0, 100, 200, 100);
CGContextClosePath(context);
CGContextAddEllipseInRect(context, CGRectMake(0, 0, 100, 200));
CGContextAddRect(context, CGRectMake(200, 400, 100, 200));
CGContextDrawPath(context, kCGPathStroke);
創(chuàng)建路徑
在開始繪制路徑前业汰,調(diào)用 CGContextBeginPath 或 UI伙窃。
直線、弧样漆、曲線開始于當(dāng)前點(diǎn)为障。空路徑?jīng)]有當(dāng)前點(diǎn);我們必須調(diào)用CGContextMoveToPoint來設(shè)置第一個(gè)子路徑的起始點(diǎn),或者調(diào)用一個(gè)便利函數(shù)來隱式地完成該任務(wù)蒿柳。
如果要閉合當(dāng)前子路徑,調(diào)用函數(shù) CGContextClosePath鞋喇。隨后路徑將開始一個(gè)新的子路徑,即使我們不顯示設(shè)置一個(gè)新的起始點(diǎn)眉撵。
當(dāng)繪制弧時(shí)侦香,Quartz 將在當(dāng)前點(diǎn)與弧的起始點(diǎn)間繪制一條直線。
添加橢圓和矩形的 Quartz 程序?qū)⒃诼窂街刑砑有碌拈]合子路徑纽疟。
我們必須調(diào)用繪制函數(shù)來填充或者描邊一條路徑罐韩,因?yàn)閯?chuàng)建路徑時(shí)并不會(huì)繪制路徑。
Quartz 提供了兩個(gè)數(shù)據(jù)類型來創(chuàng)建可復(fù)用路徑 CGPathRef 和 CGMutablePathRef污朽。
Quartz 提供了一個(gè)類似于操作圖形上下文的 CGPath 的函數(shù)集合伴逸。這些路徑函數(shù)操作 CGPath 對(duì)象,而不是圖形上下文。
- CGPathCreateMutable 取代 CGContextBeginPath
- CGPathMoveToPoint 取代 CGContextMoveToPoint
- CGPathAddLineToPoint 取代 CGContexAddLineToPoint
- CGPathAddCurveToPoint 取代 CGContexAddCurveToPoint
- CGPathAddEllipseInRect 取代 CGContexAddEllipseInRect
- CGPathAddArc 取代 CGContexAddArc
- CGPathAddRect 取代 CGContexAddRect
- CGPathCloseSubpath 取代 CGContexClosePath
- 如果想要添加一個(gè)路徑到圖形上下文错蝴,可以調(diào)用 CGContextAddPath。
填充規(guī)則
填充規(guī)則有兩種:非零纏繞數(shù)規(guī)則(nonzero winding number rule)颓芭、偶數(shù)-奇數(shù)規(guī)則(even-odd rule)顷锰。
默認(rèn)的填充規(guī)則為非零纏繞數(shù)規(guī)則。方法或枚舉帶有“EO”的為偶數(shù)-奇數(shù)規(guī)則亡问。
-
非零纏繞數(shù)的填充規(guī)則與繪制的方向有關(guān)官紫、偶數(shù)-奇數(shù)規(guī)則則與方向無關(guān)。如圖州藕。
繪制路徑
調(diào)用 CGContextDrawPath(context, kCGPathFill) 填充路徑束世。
調(diào)用 CGContextDrawPath(context, kCGPathEOFill) 使用奇偶規(guī)則填充路徑。
調(diào)用 CGContextDrawPath(context, kCGPathStroke) 描邊路徑床玻。
調(diào)用 CGContextDrawPath(context, kCGPathFillStroke) 填充并描邊路徑毁涉。
調(diào)用 CGContextDrawPath(context, kCGPathEOFillStroke) 使用奇偶規(guī)則填充并描邊路徑。
描邊路徑
調(diào)用快捷方法 CGContextStrokePath(context) 來描邊路徑锈死。
調(diào)用如下函數(shù)來快捷的創(chuàng)建形狀路徑并描邊贫堰。
CGContextStrokeRect(context, CGRectMake(200, 400, 100, 200));
CGContextStrokeRectWithWidth(context, CGRectMake(200, 400, 100, 200), 2);
CGContextStrokeEllipseInRect(context, CGRectMake(200, 400, 100, 200));
- 調(diào)用 CGContextStrokeLineSegments(context, points, 4) 快捷的創(chuàng)建多條不連續(xù)的線段并描邊。
CGPoint point2 = CGPointMake(200, 200);
CGPoint point3 = CGPointMake(200, 400);
CGPoint point4 = CGPointMake(100, 300);
CGPoint point5 = CGPointMake(300, 300);
CGPoint points[4] = {point2, point3, point4, point5};
CGContextStrokeLineSegments(context, points, 4);
填充路徑
調(diào)用快捷方法 CGContextFillPath(context) 或 CGContextEOFillPath(context) 填充路徑待牵。
CGContextStrokePath(context) 和 CGContextFillPath(context) 不能同時(shí)使用其屏。
調(diào)用如下函數(shù)來快捷的創(chuàng)建形狀路徑并填充。
CGContextFillRect(context, CGRectMake(100, 100, 100, 200));
CGRect rects[2] = {CGRectMake(100, 100, 100, 200), CGRectMake(200, 300, 100, 200)};
CGContextFillRects(context, rects, 2);
CGContextFillEllipseInRect(context, CGRectMake(100, 100, 100, 200));
混合模式
調(diào)用 CGContextSetBlendMode(context, kCGBlendModeNormal) 設(shè)置回合模式缨该。
常用的混合模式:
- kCGBlendModeNormal 正常
- kCGBlendModeMultiply 正片疊底
- kCGBlendModeScreen 濾色(屏幕)
- kCGBlendModeOverlay 疊加
- kCGBlendModeDarken 變暗
- kCGBlendModeLighten 變亮
- kCGBlendModeColorDodge 顏色減淡
- kCGBlendModeColorBurn 顏色加深
- kCGBlendModeSoftLight 柔光
- kCGBlendModeHardLight 強(qiáng)光
- kCGBlendModeDifference 差值
- kCGBlendModeExclusion 排除
- kCGBlendModeHue 色相
- kCGBlendModeSaturation 飽和度
- kCGBlendModeColor 顏色
- kCGBlendModeLuminosity 明度
- 你可以在《Quartz 2D Programming Guide》官方文檔中的 Paths 章節(jié)和 Bitmap Images and Image Masks 章節(jié)的最后部分查看混合模式的具體效果偎行。這里的混合模式與常用的圖形軟件(如 Photoshop)的混合模式效果相同,這里只展示正片疊底和濾色兩種效果贰拿。
-
原圖
-
正片疊底
-
濾色
顏色與顏色空間
簡介
Quartz 中的顏色是用一組數(shù)值來表示蛤袒。而顏色空間用于解析這些顏色信息,常用顏色空間有 RGB 壮不、CMYK等汗盘。
Quartz 支持通用顏色空間、設(shè)備獨(dú)立顏色空間询一、設(shè)備依賴顏色空間隐孽、索引顏色空間和模式(Pattern)顏色空間。
iOS不支持設(shè)備獨(dú)立顏色空間和通用顏色空間健蕊。iOS應(yīng)用程序必須使用設(shè)備顏色空間菱阵。
透明度
使用 CGContextSetAlpha(context, 0.2) 設(shè)置透明度。
使用 CGContextClearRect 清除上下文的 alpha 通道缩功。
創(chuàng)建設(shè)備依賴顏色空間
CGColorSpaceCreateDeviceGray() 創(chuàng)建設(shè)備依賴灰度顏色空間晴及。
CGColorSpaceCreateDeviceRGB() 創(chuàng)建設(shè)備依賴RGB顏色空間。
CGColorSpaceCreateDeviceCMYK() 創(chuàng)建設(shè)備依賴CMYK顏色空間嫡锌。
調(diào)用 CGContextSetFillColorSpace(context, colorSpace) 或 CGContextSetStrokeColorSpace(context, colorSpace) 設(shè)置顏色空間虑稼。
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextSetFillColorSpace(context, colorSpace);
CGContextSetStrokeColorSpace(context, colorSpace);
- 調(diào)用如下函數(shù)來便捷的設(shè)置設(shè)備依賴RGB顏色空間并設(shè)置顏色值琳钉。
//Device RGB.
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
- 調(diào)用如下函數(shù)來便捷的設(shè)置設(shè)備依賴CMYK顏色空間并設(shè)置顏色值。
//Device CMYK.
CGContextSetCMYKStrokeColor(context, 1, 0, 0, 0, 1);
CGContextSetCMYKFillColor(context, 1, 0, 0, 0, 1);
- 調(diào)用如下函數(shù)來便捷的設(shè)置設(shè)備依賴灰度顏色空間并設(shè)置顏色值蛛倦。
//Device Gray.
CGContextSetGrayStrokeColor(context, 0.5, 1);
CGContextSetGrayFillColor(context, 0.5, 1);
- 調(diào)用如下函數(shù)來便捷的使用 CGColor 設(shè)置顏色值并使用 CGColor 指定的顏色空間歌懒。
//Any color space; you supply a CGColor object that specifies the color space. Use these functions for colors you need repeatedly.
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ù)來便捷的設(shè)置顏色值并使用正在使用的顏色空間。
//The current color space. Not recommended. Instead, set color using a CGColor object and the functions CGContextSetStrokeColorWithColor and CGContextSetFillColorWithColor.
CGContextSetStrokeColor(context, colors);
CGContextSetFillColor(context, colors);
設(shè)置和創(chuàng)建顏色
- 通過如下函數(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ù)制出來,這些不能復(fù)制的顏色叫色域外(out-of-gamut)顏色又跛。比如 RGB 顏色空間比 CMYK 的顏色空間要大碍拆,有些在顯示器上能顯示的顏色不能在打印機(jī)上同樣打印出來。因?yàn)槲覀儾荒茉谀繕?biāo)設(shè)備顏色空間中復(fù)制出色域外顏色效扫,我們必須用一些其他顏色來替代他們倔监。顏色空間轉(zhuǎn)換時(shí)顏色替換調(diào)整的規(guī)則就是再現(xiàn)意圖。更詳細(xì)的說明可以查看 這里 和 這里
再現(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) 來設(shè)置再現(xiàn)意圖。
再現(xiàn)意圖共有以下 5 種摹迷。
typedef CF_ENUM (int32_t, CGColorRenderingIntent) {
kCGRenderingIntentDefault,
kCGRenderingIntentAbsoluteColorimetric,
kCGRenderingIntentRelativeColorimetric,
kCGRenderingIntentPerceptual,
kCGRenderingIntentSaturation
};
- kCGRenderingIntentDefault:默認(rèn)再現(xiàn)意圖疟赊。
- kCGRenderingIntentAbsoluteColorimetric:絕對(duì)色度再現(xiàn)意圖。將輸出設(shè)備顏色域外的顏色映射為輸出設(shè)備域內(nèi)與之最接近的顏色峡碉。這可以產(chǎn)生一個(gè)裁減效果近哟,因?yàn)樯蛲獾膬蓚€(gè)不同的顏色值可能被映射為色域內(nèi)的同一個(gè)顏色值。當(dāng)圖形使用的顏色值同時(shí)包含在源色域及目標(biāo)色域內(nèi)時(shí)鲫寄,這種方法是最好的吉执。常用于logo或者使用專色(spot color)時(shí)。
- kCGRenderingIntentRelativeColorimetric:相對(duì)色度再現(xiàn)意圖地来。轉(zhuǎn)換所有的顏色(包括色域內(nèi)的)戳玫,以補(bǔ)償圖形上下文的白點(diǎn)與輸出設(shè)備白點(diǎn)之間的色差。
- kCGRenderingIntentPerceptual:感知再現(xiàn)意圖未斑。通過壓縮圖形上下文的色域來適應(yīng)輸出設(shè)備的色域咕宿,并保持源顏色空間的顏色之間的相對(duì)性。感知渲染意圖適用于相片及其它復(fù)雜的高細(xì)度圖片。
- kCGRenderingIntentSaturation:飽和度再現(xiàn)意圖府阀。把顏色轉(zhuǎn)換到輸出設(shè)備色域內(nèi)時(shí)缆镣,保持顏色的相對(duì)飽和度。結(jié)果是包含亮度肌似、飽和度顏色的圖片费就。飽和度意圖適用于生成低細(xì)度的圖片,如描述性圖表川队。
博客:xuyafei.cn
簡書:jianshu.com/users/2555924d8c6e
微博:weibo.com/xuyafei86
Github:github.com/xiaofei86