Quartz2D 編程指南(一)概覽、圖形上下文、路徑、顏色與顏色空間

  1. 概覽
  2. 圖形上下文
  3. 路徑
  4. 顏色與顏色空間
  5. 變換
  6. 圖案
  7. 陰影
  8. 漸變
  9. 透明層
  10. Quartz 2D 中的數(shù)據(jù)管理
  11. 位圖與圖像遮罩
  12. CoreGraphics 繪制 Layer

0.說(shuō)明

本篇博客主要是對(duì)官方文檔的總結(jié)與補(bǔ)充。翻譯部分參考了南峰子的博客。你可以在參考資料中查看。

1.概覽

簡(jiǎn)介

  • 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 中。我們可以簡(jiǎn)單地給 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ù)類型來(lái)創(chuàng)建對(duì)象,通過(guò)操作這些對(duì)象來(lái)獲取特定的圖形。
  1. CGPathRef:用于向量圖,可創(chuàng)建路徑,并進(jìn)行填充或描畫(stroke)
  2. CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩
  3. CGLayerRef:用于表示可用于重復(fù)繪制(如背景)和幕后 (offscreen)繪制的繪畫層
  4. CGPatternRef:用于重繪圖
  5. CGShadingRef、CGGradientRef:用于繪制漸變
  6. CGFunctionRef:用于定義回調(diào)函數(shù),該函數(shù)包含一個(gè)隨機(jī)的浮點(diǎn)值參數(shù)。當(dāng)為陰影創(chuàng)建漸變時(shí)使用該類型
  7. CGColorRef, CGColorSpaceRef:用于告訴Quartz如何解釋顏色
  8. CGImageSourceRef,CGImageDestinationRef:用于在Quartz中移入移出數(shù)據(jù)
  9. CGFontRef:用于繪制文本
  10. *CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用于訪問(wèn)PDF的元數(shù)據(jù)
  11. *CGPDFScannerRef, CGPDFContentStreamRef:用于解析PDF元數(shù)據(jù)
  12. *CGPSConverterRef:用于將PostScript轉(zhuǎn)化成PDF。在iOS中不能使用。

圖形狀態(tài)

  • Quartz 通過(guò)修改當(dāng)前圖形狀態(tài)(current graphics state)來(lái)修改繪制操作的結(jié)果。圖形狀態(tài)包含用于繪制程序的參數(shù)。繪制程序根據(jù)這些繪圖狀態(tài)來(lái)決定如何渲染結(jié)果。

  • 可使用函數(shù)CGContextSaveGState來(lái)保存圖形狀態(tài),CGContextRestoreGState來(lái)還原圖形狀態(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 通過(guò)使用當(dāng)前轉(zhuǎn)換矩陣(current transformation matrix, CTM)將一個(gè)獨(dú)立的坐標(biāo)系統(tǒng)(user space)映射到輸出設(shè)備的坐標(biāo)系統(tǒng)(device space),以此來(lái)解決設(shè)備依賴問(wèn)題。

  • 使用 UIGraphicsBeginImageContextWithOptions 返回的繪圖上下文與UIKit 的坐標(biāo)系統(tǒng)相同。

  • 在 iOS 中,如果使用 UIImage 對(duì)象來(lái)包裹創(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ù)來(lái)指定 retain 和 release 一個(gè)對(duì)象。例如,如果創(chuàng)建了一個(gè) CGColorspace 對(duì)象,則使用函數(shù) CGColorSpaceRetain 和 CGColorSpaceRelease 來(lái) retain 和 release 對(duì)象。同樣,可以使用 Core Foundation 的 CFRetain 和 CFRelease,但是注意不能傳遞 NULL 值給這些函數(shù)。

2.圖形上下文

簡(jiǎn)介

  • 我們可以通過(guò)兩種方式來(lái)獲取 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。我們可以通過(guò)調(diào)用 UIGraphicsGetCurrentContext 函數(shù)來(lái)獲取這個(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ù)來(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

  • iOS 中使用 UIGraphicsBeginImageContextWithOptions 取代 CGBitmapContextCreate 來(lái)創(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ù))來(lái)表示。

  • iOS 共支持 8 種像素格式。

  1. Null 8 bpp, 8 bpc, kCGImageAlphaOnly
  2. Gray 8 bpp, 8 bpc, kCGImageAlphaNone
  3. Gray 8 bpp, 8 bpc, kCGImageAlphaOnly
  4. RGB 16 bpp, 5 bpc, kCGImageAlphaNoneSkipFirst
  5. RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipFirst
  6. RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipLast
  7. RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedFirst
  8. RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedLast

抗鋸齒

  • 我們可以通過(guò)調(diào)用 CGContextSetShouldAntialias 來(lái)關(guān)閉位圖Graphics Context的反鋸齒效果。反鋸齒設(shè)置是圖形狀態(tài)的一部分。

  • 可以調(diào)用函數(shù)CGContextSetAllowsAntialiasing來(lái)控制一個(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.路徑

簡(jiǎn)介

  • 路徑定義了一個(gè)或多個(gè)形狀或者子路徑。一個(gè)子路徑可由直線,曲線,或者同時(shí)由兩者構(gòu)成。它可以是開(kāi)放的,也可以是閉合的;可以是實(shí)線,可以是曲線;可以填充,也可以描邊等等。

  • 路徑創(chuàng)建及路徑繪制是兩個(gè)獨(dú)立的工作。首先我們創(chuàng)建路徑。當(dāng)我們需要渲染路徑時(shí),我們需要使用Quartz來(lái)繪制它。

點(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)建路徑

  • 在開(kāi)始繪制路徑前,調(diào)用 CGContextBeginPath 或 UI。

  • 直線、弧、曲線開(kāi)始于當(dāng)前點(diǎn)??章窂?jīng)]有當(dāng)前點(diǎn);我們必須調(diào)用CGContextMoveToPoint來(lái)設(shè)置第一個(gè)子路徑的起始點(diǎn),或者調(diào)用一個(gè)便利函數(shù)來(lái)隱式地完成該任務(wù)。

  • 如果要閉合當(dāng)前子路徑,調(diào)用函數(shù) CGContextClosePath。隨后路徑將開(kāi)始一個(gè)新的子路徑,即使我們不顯示設(shè)置一個(gè)新的起始點(diǎn)。

  • 當(dāng)繪制弧時(shí),Quartz 將在當(dāng)前點(diǎn)與弧的起始點(diǎn)間繪制一條直線。

  • 添加橢圓和矩形的 Quartz 程序?qū)⒃诼窂街刑砑有碌拈]合子路徑。

  • 我們必須調(diào)用繪制函數(shù)來(lái)填充或者描邊一條路徑,因?yàn)閯?chuàng)建路徑時(shí)并不會(huì)繪制路徑。

  • Quartz 提供了兩個(gè)數(shù)據(jù)類型來(lái)創(chuàng)建可復(fù)用路徑 CGPathRef 和 CGMutablePathRef。

  • Quartz 提供了一個(gè)類似于操作圖形上下文的 CGPath 的函數(shù)集合。這些路徑函數(shù)操作 CGPath 對(duì)象,而不是圖形上下文。

  1. CGPathCreateMutable 取代 CGContextBeginPath
  2. CGPathMoveToPoint 取代 CGContextMoveToPoint
  3. CGPathAddLineToPoint 取代 CGContexAddLineToPoint
  4. CGPathAddCurveToPoint 取代 CGContexAddCurveToPoint
  5. CGPathAddEllipseInRect 取代 CGContexAddEllipseInRect
  6. CGPathAddArc 取代 CGContexAddArc
  7. CGPathAddRect 取代 CGContexAddRect
  8. 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ī)則則與方向無(wú)關(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) 來(lái)描邊路徑。

  • 調(diào)用如下函數(shù)來(lái)快捷的創(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ù)來(lái)快捷的創(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è)置回合模式。

  • 常用的混合模式:

  1. kCGBlendModeNormal 正常
  2. kCGBlendModeMultiply 正片疊底
  3. kCGBlendModeScreen 濾色(屏幕)
  4. kCGBlendModeOverlay 疊加
  5. kCGBlendModeDarken 變暗
  6. kCGBlendModeLighten 變亮
  7. kCGBlendModeColorDodge 顏色減淡
  8. kCGBlendModeColorBurn 顏色加深
  9. kCGBlendModeSoftLight 柔光
  10. kCGBlendModeHardLight 強(qiáng)光
  11. kCGBlendModeDifference 差值
  12. kCGBlendModeExclusion 排除
  13. kCGBlendModeHue 色相
  14. kCGBlendModeSaturation 飽和度
  15. kCGBlendModeColor 顏色
  16. kCGBlendModeLuminosity 明度
  • 你可以在《Quartz 2D Programming Guide》官方文檔中的 Paths 章節(jié)和 Bitmap Images and Image Masks 章節(jié)的最后部分查看混合模式的具體效果。這里的混合模式與常用的圖形軟件(如 Photoshop)的混合模式效果相同,這里只展示正片疊底和濾色兩種效果。
  1. 原圖


  2. 正片疊底


  3. 濾色


顏色與顏色空間

簡(jiǎn)介

  • Quartz 中的顏色是用一組數(shù)值來(lái)表示。而顏色空間用于解析這些顏色信息,常用顏色空間有 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ù)來(lái)便捷的設(shè)置設(shè)備依賴RGB顏色空間并設(shè)置顏色值。
//Device RGB. 
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
  • 調(diào)用如下函數(shù)來(lái)便捷的設(shè)置設(shè)備依賴CMYK顏色空間并設(shè)置顏色值。
//Device CMYK. 
CGContextSetCMYKStrokeColor(context, 1, 0, 0, 0, 1);
CGContextSetCMYKFillColor(context, 1, 0, 0, 0, 1);
  • 調(diào)用如下函數(shù)來(lái)便捷的設(shè)置設(shè)備依賴灰度顏色空間并設(shè)置顏色值。
//Device Gray.
CGContextSetGrayStrokeColor(context, 0.5, 1);
CGContextSetGrayFillColor(context, 0.5, 1);
  • 調(diào)用如下函數(shù)來(lái)便捷的使用 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ù)來(lái)便捷的設(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)建顏色

  • 通過(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)意圖。更詳細(xì)的說(shuō)明可以查看 這里這里

  • 再現(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,
    kCGRenderingIntentAbsoluteColorimetric,
    kCGRenderingIntentRelativeColorimetric,
    kCGRenderingIntentPerceptual,
    kCGRenderingIntentSaturation
};
  1. kCGRenderingIntentDefault:默認(rèn)再現(xiàn)意圖。
  2. 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í)。
  3. kCGRenderingIntentRelativeColorimetric:相對(duì)色度再現(xiàn)意圖。轉(zhuǎn)換所有的顏色(包括色域內(nèi)的),以補(bǔ)償圖形上下文的白點(diǎn)與輸出設(shè)備白點(diǎn)之間的色差。
  4. kCGRenderingIntentPerceptual:感知再現(xiàn)意圖。通過(guò)壓縮圖形上下文的色域來(lái)適應(yīng)輸出設(shè)備的色域,并保持源顏色空間的顏色之間的相對(duì)性。感知渲染意圖適用于相片及其它復(fù)雜的高細(xì)度圖片。
  5. kCGRenderingIntentSaturation:飽和度再現(xiàn)意圖。把顏色轉(zhuǎn)換到輸出設(shè)備色域內(nèi)時(shí),保持顏色的相對(duì)飽和度。結(jié)果是包含亮度、飽和度顏色的圖片。飽和度意圖適用于生成低細(xì)度的圖片,如描述性圖表。

博客:xuyafei.cn
簡(jiǎn)書:jianshu.com/users/2555924d8c6e
微博:weibo.com/xuyafei86
Github:github.com/xiaofei86

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容