核心繪圖狀態(tài)管理
CGContextSaveGState函數(shù)的作用是將當(dāng)前圖形狀態(tài)推入堆棧。之后,您對(duì)圖形狀態(tài)所做的修改會(huì)影響隨后的描畫操作,但不影響存儲(chǔ)在堆棧中的拷貝。在修改完成后,您可以通過CGContextRestoreGState函數(shù)把堆棧頂部的狀態(tài)彈出,返回到之前的圖形狀態(tài)。這種推入和彈出的方式是回到之前圖形狀態(tài)的快速方法,避免逐個(gè)撤消所有的狀態(tài)修改;這也是將某些狀態(tài)(比如裁剪路徑)恢復(fù)到原有設(shè)置的唯一方式。
CGContextSaveGState:壓棧操作,保存一份當(dāng)前圖形上下文
CGContextRestoreGState:出棧操作,恢復(fù)一份當(dāng)前圖形上下文
圖形上下文的坐標(biāo)空間變換
CTM(current transformation matrix當(dāng)前轉(zhuǎn)換矩陣)
CGContextScaleCTM:坐標(biāo)系X,Y縮放
CGContextTranslateCTM:坐標(biāo)系平移
CGContextRotateCTM:坐標(biāo)系旋轉(zhuǎn)
CGContextConcatCTM:
CGContextGetCTM:獲得一份CTM
設(shè)置Line屬性及連接樣式
CGContextSetLineWidth:
CGContextSetLineCap:
CGContextSetLineJoin:
CGContextSetMiterLimit:
CGContextSetLineDash:
CGContextSetFlatness:
CGContextSetAlpha://設(shè)置透明度
CGContextSetAlpha(context, 0.2)
CGContextSetBlendMode:
設(shè)置Path繪制
CGContextBeginPath:
CGContextMoveToPoint:畫筆移動(dòng)到該點(diǎn)開始畫線
CGContextAddLineToPoint:畫直線到該點(diǎn)
CGContextAddCurveToPoint:畫三次曲線函數(shù)
CGContextMoveToPoint(context, 200, 300);//設(shè)置Path的起點(diǎn)
CGContextAddCurveToPoint(context,250, 280, 250, 400, 280, 300);//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo)和控制點(diǎn)坐標(biāo)終點(diǎn)坐標(biāo)
CGContextStrokePath(context);
CGContextAddQuadCurveToPoint:畫二次曲線
CGContextMoveToPoint(context, 120, 300);//設(shè)置Path的起點(diǎn)
CGContextAddQuadCurveToPoint(context,190, 310, 120, 390);//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo)
CGContextStrokePath(context);
CGContextClosePath:閉合曲線
CGContextAddRect:畫矩形
CGContextAddRect(context,CGRectMake(140, 120, 60, 30));//畫方框
CGContextAddRects:
CGContextAddLines:
/*畫三角形*/
//只要三個(gè)點(diǎn)就行跟畫一條線方式一樣,把三點(diǎn)連接起來(lái)
CGPoint sPoints[3];//坐標(biāo)點(diǎn)
sPoints[0] =CGPointMake(100, 220);//坐標(biāo)1
sPoints[1] =CGPointMake(130, 220);//坐標(biāo)2
sPoints[2] =CGPointMake(130, 160);//坐標(biāo)3
CGContextAddLines(context, sPoints, 3);//添加線
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke); //根據(jù)坐標(biāo)繪制路徑
CGContextAddEllipseInRect:
//畫橢圓
CGContextAddEllipseInRect(context, CGRectMake(160, 180, 20, 8)); //橢圓
CGContextDrawPath(context, kCGPathFillStroke);
CGContextAddArc:
CGContextAddArcToPoint:
/*畫圓角矩形*/
float fw = 180;
float fh = 280;
CGContextMoveToPoint(context, fw, fh-20); // 開始坐標(biāo)右邊開始
CGContextAddArcToPoint(context, fw, fh, fw-20, fh, 10); // 右下角角度
CGContextAddArcToPoint(context, 120, fh, 120, fh-20, 10); // 左下角角度
CGContextAddArcToPoint(context, 120, 250, fw-20, 250, 10); // 左上角
CGContextAddArcToPoint(context, fw, 250, fw, fh-20, 10); // 右上角
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke); //根據(jù)坐標(biāo)繪制路徑
CGContextAddPath:
CGContextCopyPath:
獲取路徑信息
CGContextReplacePathWithStrokedPath:
CGContextIsPathEmpty:表示目前的圖形上下文是否包含任何的子路徑。
bool isPathEmpty = CGContextIsPathEmpty(ctf);
CGContextGetPathCurrentPoint:返回一個(gè)非空的路徑中的當(dāng)前點(diǎn)。
CGPoint currentPoint = CGContextGetPathCurrentPoint(ctf);// 獲取當(dāng)前畫筆處于最后的那一個(gè)點(diǎn)
CGContextGetPathBoundingBox:返回包含當(dāng)前路徑的最小矩形。
CGRect boxRect = CGContextGetPathBoundingBox(ctf);// 包含路徑的最小矩形
CGContextPathContainsPoint:檢查當(dāng)前路徑中是否包含指定的點(diǎn)。
路徑繪制
CGContextStrokePath:
CGContextDrawPath:
兩者區(qū)別:
/*CGPathDrawingMode是填充方式,枚舉類型
kCGPathFill:只有填充(非零纏繞數(shù)填充),不繪制邊框
kCGPathEOFill:奇偶規(guī)則填充(多條路徑交叉時(shí),奇數(shù)交叉填充,偶交叉不填充)
kCGPathStroke:只有邊框
kCGPathFillStroke:既有邊框又有填充
kCGPathEOFillStroke:奇偶填充并繪制邊框
*/
CGContextStrokePath(context); 直接在圖形上下文中渲染路徑
CGContextDrawPath(context, kCGPathFillStroke); //指定模式下渲染路徑
CGContextFillPath://填充路徑
CGContextEOFillPath://奇偶填充
CGContextFillRect://
CGContextStrokeRect:
/*畫矩形*/
CGContextStrokeRect(context,CGRectMake(100, 120, 10, 10));//畫方框
CGContextFillRect(context,CGRectMake(120, 120, 10, 10));//填充框
CGContextFillRects:
CGContextStrokeRectWithWidth:
CGContextClearRect:
CGContextFillEllipseInRect:
CGContextStrokeEllipseInRect:
CGContextStrokeLineSegments:
修改剪裁路徑
CGContextClip:
CGContextEOClip:
CGContextClipToMask:
CGContextGetClipBoundingBox:
CGContextClipToRect:
CGContextClipToRects:
設(shè)置顏色、色彩空間及陰影值
Quartz 中的顏色是用一組數(shù)值來(lái)表示。而顏色空間用于解析這些顏色信息,常用顏色空間有 RGB 、CMYK等。
Quartz 支持通用顏色空間、設(shè)備獨(dú)立顏色空間、設(shè)備依賴顏色空間、索引顏色空間和模式(Pattern)顏色空間。
iOS不支持設(shè)備獨(dú)立顏色空間和通用顏色空間。iOS應(yīng)用程序必須使用設(shè)備顏色空間。
CGContextSetFillColorWithColor://設(shè)置填充顏色
CGContextSetStrokeColorWithColor://設(shè)置描邊顏色
- 調(diào)用如下函數(shù)來(lái)便捷的使用 CGColor 設(shè)置顏色值并使用 CGColor 指定的顏色空間
//設(shè)置填充顏色
UIColor *aColor = [UIColor blueColor];//blue藍(lán)色
CGContextSetFillColorWithColor(context, aColor.CGColor);//填充顏色
//設(shè)置描邊顏色
aColor = [UIColor yellowColor];
CGContextSetStrokeColorWithColor(context, aColor.CGColor);//線框顏色
創(chuàng)建設(shè)備依賴顏色空間
Quartz 中的顏色是用一組數(shù)值來(lái)表示。而顏色空間用于解析這些顏色信息,常用顏色空間有 RGB 、CMYK等。
Quartz 支持通用顏色空間、設(shè)備獨(dú)立顏色空間、設(shè)備依賴顏色空間、索引顏色空間和模式(Pattern)顏色空間。
iOS不支持設(shè)備獨(dú)立顏色空間和通用顏色空間。iOS應(yīng)用程序必須使用設(shè)備顏色空間。
- CGColorSpaceCreateDeviceGray() 創(chuàng)建設(shè)備依賴灰度顏色空間。
- CGColorSpaceCreateDeviceRGB() 創(chuàng)建設(shè)備依賴RGB顏色空間。
- CGColorSpaceCreateDeviceCMYK() 創(chuàng)建設(shè)備依賴CMYK顏色
空間。
CGContextSetFillColorSpace:
CGContextSetStrokeColorSpace:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextSetFillColorSpace(context, colorSpace);
CGContextSetStrokeColorSpace(context, colorSpace);
CGContextSetFillColor:
CGContextSetStrokeColor:
//Device RGB.
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
CGContextSetGrayFillColor:
CGContextSetGrayStrokeColor:
- 調(diào)用如下函數(shù)來(lái)便捷的設(shè)置設(shè)備依賴CMYK顏色空間并設(shè)置顏色值。
//Device Gray.
CGContextSetGrayStrokeColor(context, 0.5, 1);
CGContextSetGrayFillColor(context, 0.5, 1);
CGContextSetRGBFillColor:
CGContextSetRGBStrokeColor:
CGContextSetRGBStrokeColor (context, 142.0/ 255.0, 161.0/ 255.0, 189.0/ 255.0, 1.0);
CGContextSetCMYKFillColor:
CGContextSetCMYKStrokeColor:
- 調(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);
CGContextSetRenderingIntent:設(shè)置再現(xiàn)意圖
每個(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ì)的說明可以查看 這里 和 這里
再現(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)意圖。通過壓縮圖形上下文的色域來(lái)適應(yīng)輸出設(shè)備的色域,并保持源顏色空間的顏色之間的相對(duì)性。感知渲染意圖適用于相片及其它復(fù)雜的高細(xì)度圖片。
5 kCGRenderingIntentSaturation:飽和度再現(xiàn)意圖。把顏色轉(zhuǎn)換到輸出設(shè)備色域內(nèi)時(shí),保持顏色的相對(duì)飽和度。結(jié)果是包含亮度、飽和度顏色的圖片。飽和度意圖適用于生成低細(xì)度的圖片,如描述性圖表。
CGContextDrawImage:在指定區(qū)域畫圖片
/*圖片*/
UIImage *image = [UIImage imageNamed:@"apple.jpg"];
[image drawInRect:CGRectMake(60, 340, 20, 20)];//在坐標(biāo)中畫出圖片
// [image drawAtPoint:CGPointMake(100, 340)];//保持圖片大小在point點(diǎn)開始畫圖片,可以把注釋去掉看看
CGContextDrawImage(context, CGRectMake(100, 340, 20, 20), image.CGImage);
CGContextDrawTiledImage:
CGContextGetInterpolationQuality:返回當(dāng)前的圖形上下文的插值(插值(Interpolation)是在不天生像素的環(huán)境下增長(zhǎng)圖像像素大小的一種方法,在周圍像素色彩
的根蒂根基上用算術(shù)公式計(jì)算亡失像素的色彩。)質(zhì)量水平
CGContextSetInterpolationQuality:設(shè)置圖形上下文的插值質(zhì)量水平。
設(shè)置陰影
CGContextSetShadowWithColor:
CGContextSetShadow:
陰影是如何工作的
Quartz中的陰影是圖形狀態(tài)的一部分。我們可以調(diào)用函數(shù)CGContextSetShadow來(lái)創(chuàng)建,并傳入一個(gè)圖形上下文、偏移值及模糊值。陰影被設(shè)置后,任何繪制的對(duì)象都有一個(gè)陰影,且該陰影在設(shè)備RGB顏色空間中呈現(xiàn)出黑色的且alpha值為1/3。換句話說,陰影是用RGBA值{0, 0, 0, 1.0/3.0}設(shè)置的。
我們可以調(diào)用函數(shù)CGContextSetShadowWithColor來(lái)設(shè)置彩色陰影,并傳遞一個(gè)圖形上下文、 偏移值、模糊值有CGColor顏色對(duì)象。顏色值依賴于顏色空間。
如何在調(diào)用CGContextSetShadow或CGContextSetShadowWithColor之前保存了圖形狀態(tài),我們可以通過恢復(fù)圖形狀態(tài)來(lái)關(guān)閉陰影。我們也可以通過設(shè)置陰影顏色為NULL來(lái)關(guān)閉陰影
陰影有三個(gè)屬性:
x偏移值,用于指定陰影相對(duì)于圖片在水平方向上的偏移值。
y偏移值,用于指定陰影相對(duì)于圖片在豎直方向上的偏移值。
模糊(blur)值,用于指定圖像是有一個(gè)硬邊
CGContextSetShadow(context, CGSizeMake(10, -20), 10);
繪制漸變色
CGContextDrawLinearGradient:
CGContextDrawRadialGradient:
//第二種填充方式
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGFloat colors[] =
{
1,1,1, 1.00,
1,1,0, 1.00,
1,0,0, 1.00,
1,0,1, 1.00,
0,1,1, 1.00,
0,1,0, 1.00,
0,0,1, 1.00,
0,0,0, 1.00,
};
CGGradientRef gradient = CGGradientCreateWithColorComponents
(rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));//形成梯形,漸變的效果
CGColorSpaceRelease(rgb);
//畫線形成一個(gè)矩形
//CGContextSaveGState與CGContextRestoreGState的作用
/*
CGContextSaveGState函數(shù)的作用是將當(dāng)前圖形狀態(tài)推入堆棧。之后,您對(duì)圖形狀態(tài)所做的修改會(huì)影響隨后的描畫操作,但不影響存儲(chǔ)在堆棧中的拷貝。在修改完成后,您可以通過CGContextRestoreGState函數(shù)把堆棧頂部的狀態(tài)彈出,返回到之前的圖形狀態(tài)。這種推入和彈出的方式是回到之前圖形狀態(tài)的快速方法,避免逐個(gè)撤消所有的狀態(tài)修改;這也是將某些狀態(tài)(比如裁剪路徑)恢復(fù)到原有設(shè)置的唯一方式。
*/
CGContextSaveGState(context);
CGContextMoveToPoint(context, 220, 90);
CGContextAddLineToPoint(context, 240, 90);
CGContextAddLineToPoint(context, 240, 110);
CGContextAddLineToPoint(context, 220, 110);
CGContextClip(context);//context裁剪路徑,后續(xù)操作的路徑
//CGContextDrawLinearGradient(CGContextRef context,CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint,CGGradientDrawingOptions options)
//gradient漸變顏色,startPoint開始漸變的起始位置,endPoint結(jié)束坐標(biāo),options開始坐標(biāo)之前or開始之后開始漸變
CGContextDrawLinearGradient(context, gradient,CGPointMake
(220,90) ,CGPointMake(240,110),
kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(context);// 恢復(fù)到之前的context
//再寫一個(gè)看看效果
CGContextSaveGState(context);
CGContextMoveToPoint(context, 260, 90);
CGContextAddLineToPoint(context, 280, 90);
CGContextAddLineToPoint(context, 280, 190);
CGContextAddLineToPoint(context, 260, 190);
CGContextClip(context);//裁剪路徑
//說白了,開始坐標(biāo)和結(jié)束坐標(biāo)是控制漸變的方向和形狀
CGContextDrawLinearGradient(context, gradient,CGPointMake
(260, 90) ,CGPointMake(260, 190),
kCGGradientDrawsAfterEndLocation);
CGContextRestoreGState(context);// 恢復(fù)到之前的context
//下面再看一個(gè)顏色漸變的圓
//參數(shù)1:圖形上下文
//參數(shù)2:漸變色
//參數(shù)3:開始中心點(diǎn)
//參數(shù)4:開始半徑
//參數(shù)5:結(jié)束中心點(diǎn)
//參數(shù)6:結(jié)束半徑
//參數(shù)7:渲染模式
CGContextDrawRadialGradient(context, gradient, CGPointMake(400, 100), 0.0, CGPointMake(350, 100), 30, kCGGradientDrawsBeforeStartLocation);
CGContextDrawShading:
繪制文本
CGContextSetCharacterSpacing:
CGContextSetTextPosition:
CGContextGetTextPosition:
CGContextSetTextMatrix:
CGContextGetTextMatrix:
CGContextSetTextDrawingMode:
CGContextSetFont:
CGContextSetFontSize:
CGContextShowGlyphsAtPositions:
** CGContextDrawPDFPage**: 繪制一個(gè)PDF頁(yè)面到當(dāng)前的用戶空間
建立一個(gè)基于頁(yè)面的圖形上下文
CGContextBeginPage:
CGContextEndPage:
管理圖形上下文
CGContextRetain:
CGContextRelease:
CGContextSynchronize:
鋸齒功能
CGContextSetShouldAntialias:設(shè)置圖形上下文的抗鋸齒開啟或關(guān)閉。
CGContextSetAllowsAntialiasing:
字體展示功能
CGContextSetShouldSmoothFonts:
CGContextSetAllowsFontSmoothing:
CGContextSetShouldSubpixelPositionFonts:
CGContextSetAllowsFontSubpixelPositioning:
CGContextSetShouldSubpixelQuantizeFonts:
CGContextSetAllowsFontSubpixelQuantization:
使用透明圖層
Quartz的透明層類似于許多流行的圖形應(yīng)用中的層。層是獨(dú)立的實(shí)體。Quartz維護(hù)為每個(gè)上下文維護(hù)一個(gè)透明層棧,并且透明層是可以嵌套的。但由于層通常是棧的一部分,所以我們不能單獨(dú)操作它們。
我們通過調(diào)用函數(shù)CGContextBeginTransparencyLayer來(lái)開始一個(gè)透明層,該函數(shù)需要兩個(gè)參數(shù):圖形上下文與CFDictionary對(duì)象。字典中包含我們所提供的指定層額外信息的選項(xiàng),但由于Quartz 2D API中沒有使用字典,所以我們傳遞一個(gè)NULL。在調(diào)用這個(gè)函數(shù)后,圖形狀態(tài)參數(shù)保持不變,除了alpha值[默認(rèn)設(shè)置為1]、陰影[默認(rèn)關(guān)閉]、混合模式[默認(rèn)設(shè)置為normal]、及其它影響最終組合的參數(shù)。
在開始透明層操作后,我們可以繪制任何想顯示在層上的對(duì)象。指定上下文中的繪制操作將被當(dāng)成一個(gè)組合對(duì)象繪制到一個(gè)透明背景上。這個(gè)背景被當(dāng)作一個(gè)獨(dú)立于圖形上下文的目標(biāo)緩存。
當(dāng)繪制完成后,我們調(diào)用函數(shù)CGContextEndTransparencyLayer。Quartz將結(jié)合對(duì)象放入上下文,并使用上下文的全局alpha值、陰影狀態(tài)及裁減區(qū)域作用于組合對(duì)象。
在透明層中繪制需要三步:
- 調(diào)用函數(shù)CGContextBeginTransparencyLayer
- 在透明層中繪制需要組合的對(duì)象
- 調(diào)用函數(shù)CGContextEndTransparencyLayer
CGContextBeginTransparencyLayer:直到相應(yīng)的調(diào)用CGContextEndTransparencyLayer,在指定范圍內(nèi)的所有后續(xù)繪制操作組合到一個(gè)完全透明的背景(它被視為一個(gè)單獨(dú)的目標(biāo)緩沖區(qū)從上下文)
CGContextBeginTransparencyLayerWithRect:
CGContextEndTransparencyLayer:
//代碼示例:
CGContextBeginTransparencyLayer(context, NULL);
CGFloat wd = 300;
CGFloat ht = 300;
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGContextFillRect(context, CGRectMake (wd/3 + 50, ht/2, wd/4, ht/4));
CGContextEndTransparencyLayer(context);
用戶空間與設(shè)備空間互換
CGContextGetUserSpaceToDeviceSpaceTransform:
CGContextConvertPointToDeviceSpace:
CGContextConvertPointToUserSpace:
CGContextConvertSizeToDeviceSpace:
CGContextConvertSizeToUserSpace:
CGContextConvertRectToDeviceSpace:
CGContextConvertRectToUserSpace: