這篇文章就對這兩個context 做一個詳細的介紹逛拱。
CGContext
屬于Core Graphics(使用Quartz 進行2D渲染偏塞,處理基于路徑的繪圖、抗鋸齒渲染寒屯、漸變罕偎、圖像洛心、顏色管理儿奶、pdf文檔等宝与。 說白了就是2D繪圖 渲染功能)框架.
我們平時用的其實都是他的引用類型 CGContextRef
typedef struct CGContext *CGContextRef;
同時也發(fā)現(xiàn)喜滨,CGContext是一個結(jié)構(gòu)體捉捅,而并不是一個Object。CGContextRef是一個指向CGContext結(jié)構(gòu)體的指針虽风。
其實 Core Graphics 其中的類型棒口,都和這個類似。如:
CGColor ---> CGColorRef
CGPath ---> CGPathRef
CGImage ---> CGImageRef
CGLayer ---> CGLayerRef
CGShading---> CGShadingRef
CGFont ---> CGFontRef
CGPDFObject-> CGPDFObjectRef
CGContext 可以看做是一個2D 作圖的畫布辜膝。 而iOS 有多種畫布无牵,這些畫布都以堆棧的形式存放。(只有最上面的那個context才有效厂抖,有push pop的概念)
- 獲取CGContextRef
1. UIGraphicsGetCurrentContext ()
在 -(void)drawRect:(CGRect)rect 里面獲取contex的方法茎毁。
2. UIGraphicsPushContext(ctx)
UIGraphicsPopContext()
也就是壓入棧 和 推出棧,
在 -(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
里面調(diào)用即可吧當前的context 放到棧頂忱辅,方能生效七蜘。
//該函數(shù)會自動創(chuàng)建一個context谭溉,并把它push到上下文棧頂
//開始 scale 為0 則表示跟隨設(shè)備,opaque YES黑色畫布橡卤,NO透明畫布
3. UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
UIGraphicsBeginImageContext(size)//開始
UIGraphicsGetCurrentContext()//獲取context
UIGraphicsGetImageFromCurrentImageContext() //獲取圖片
UIGraphicsEndImageContext() //結(jié)束
- 在Context上畫
1. image drawInRect
2. layer renderInContext
3. CGContextSet... //color, width, line, render, blendMode, should...
CGContextAdd... //Line, Path, Arc, Ellipse,
CGContextDraw/Fill ... //rect, path, stroke, replace
4. CGContextDrawImage(ctx, rect, image)
5. CGContextDrawShading(ctx, shading)
6. CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, options); //漸變
7. CGContextDrawPDFPage(ctx, PDFPage);
8. CGContextShowGlyphsAtPositions(ctx, glyphs, *Lpositions, count);//雕文
9.CGContextShowText(ctx, *string, length)//已作廢夜只,用CoreText 實現(xiàn)
- 坐標互轉(zhuǎn): Converting(基本上看,名字都能明白是什么意思)
CGContextGetUserSpaceToDeviceSpaceTransform //Transform
CGContextConvertPointToDeviceSpace
CGContextConvertPointToUserSpace
CGContextConvertSizeToDeviceSpace
CGContextConvertSizeToUserSpace
CGContextConvertRectToDeviceSpace
CGContextConvertRectToUserSpace
- CTM (current graphics state's transformation matrix 當前圖形狀態(tài)的轉(zhuǎn)換矩陣)
//在上下文中得到的CTM是:CTMnew = transform * CTMcontext蒜魄。
CGContextConcatCTM(ctx, transform) //矩陣 相乘(順序固定的)
//在上下文中得到CTM
CGContextGetCTM(ctx)
CGContextRotateCTM //旋轉(zhuǎn)
CGContextTranslateCTM //位移
CGContextScaleCTM //縮放
- 保存扔亥,重設(shè) context的狀態(tài)
CGContextSaveGState(ctx) 保存當前的context的狀態(tài)到堆棧上
CGContextRestoreGState(ctx) 把堆棧上第一個contex的保存狀態(tài),重新設(shè)置回去
CGContextGetTypeID 上下文的標識ID
CGContextFlush 強制吧所有的draw 都更新到contex(一般是系統(tǒng)周期性的自動調(diào)用 更新畫布)
CGContextSynchronize更新畫布谈为,系統(tǒng)在下次刷新時旅挤,draw所有操作。(相當于 做了一個需要更新的標記)
CIContext
CIContext 屬于Core Image框架(文檔中提到 主要的功能就是 用內(nèi)置或自定義的過濾器處理圖片和視頻 以及 在視頻圖片中檢測面部和眼睛子類的特征和跟蹤面部伞鲫。和Core Graphics的主要區(qū)別 就是更注重于視頻圖片的加工處理)的粘茄,是一個OC對象。一般和 CIImage秕脓,CIColor柒瓣,CIFilter等交互。
- 創(chuàng)建CIContext:
1. + contextWithOptions / + context
2. + contextWithCGContext:options: //CPU 渲染(用到了CGContextRef)
3. + contextWithCGLContext:pixelFormat:colorSpace:options: //GPU渲染(OpenGL 包含GL的)
- 在畫布上畫:
//獲取 渲染的圖片(CIImage -> CGImage)
creatCGImage:fromRect ...
render:to ... //Bitmap吠架, CVPixelBuffer芙贫, IOSurface, MTLTexture(一個支持GPU加速3D繪圖的API)
//在context上畫 圖片
- drawImage:inRect:fromRect:
二者的關(guān)聯(lián), 使用:
CIImage * outputImage = [filter outputImage]; //從CIFilter 獲取CIImage
CGRect qrRect = [colorImage extent];
//設(shè)置CIContext傍药,并從CIImage -> CGImage -> UIImage
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage: outputImage fromRect:qrRect];
UIImage *resultIamge = [UIImage imageWithCGImage:cgImage];
//(如果 直接用[UIImage imageWithCIImage:outputImage]; 會得到一個不是位圖的圖片)
UIImage* deviceImage = [UIImage imageNamed:@"device"];
//開始Image的CGContext
UIGraphicsBeginImageContext(CGSizeMake(1000, 1000));
//獲取 image的 CGContextRef
CGContextRef cgContext = UIGraphicsGetCurrentContext();
//CGContextRef 和 CIContext 關(guān)聯(lián)(二者表示同一畫布)
context = [CIContext contextWithCGContext:cgContext options:nil];
CIImage* deviceCIImage = [CIImage imageWithCGImage:deviceImage.CGImage];
CIImage* resultCIImage = [CIImage imageWithCGImage:resultIamge.CGImage];
//CIContext 吧圖片畫在context上
[context drawImage:deviceCIImage inRect:CGRectMake(0, 0, 1000, 1000) fromRect:[deviceCIImage extent]];
[context drawImage:resultCIImage inRect:CGRectMake(200, 200, 600, 600) fromRect:qrRect];
//從CGContextRef 上獲取圖片
resultIamge = UIGraphicsGetImageFromCurrentImageContext();
//結(jié)束Image的CGContext
UIGraphicsEndImageContext();
從上面磺平,可以發(fā)現(xiàn)。這兩個context 都是畫布的意思拐辽,相似的地方非常多拣挪,而且可以互相關(guān)聯(lián)。只是所屬的庫不同俱诸,在用法上有些區(qū)別菠劝。
還有一個,就是CIImage 只有經(jīng)過context 轉(zhuǎn)化為CGImage后睁搭,才能變成位圖圖片赶诊。(非位圖圖片,不能保存到相冊介袜,不能轉(zhuǎn)換為NSData (jpeg png))