CoreGraphic框架解析(一)—— 基本概覽

版本記錄

版本號 時間
V1.0 2017.08.08

前言

quartz是一個通用的術語,用于描述在iOSMAC OS X 中整個媒體層用到的多種技術 包括圖形、動畫、音頻、適配。Quart 2D 是一組二維繪圖和渲染API,Core Graphic會使用到這組API,Quartz Core專指Core Animation用到的動畫相關的庫、API和類。CoreGraphicsUIKit下的主要繪圖系統(tǒng),頻繁的用于繪制自定義視圖。Core Graphics是高度集成于UIView和其他UIKit部分的。Core Graphics數(shù)據(jù)結構和函數(shù)可以通過前綴CG來識別。在app中很多時候繪圖等操作我們要利用CoreGraphic框架,它能繪制字符串、圖形、漸變色等等,是一個很強大的工具。下面幾篇就主要介紹CoreGraphics這個工具。

框架概覽

我們先看一下框架CoreGraphics的組成。

#import <CoreGraphics/CoreGraphics.h>

這個框架包含以下的文件。

#ifndef COREGRAPHICS_H_
#define COREGRAPHICS_H_

#include <CoreGraphics/CGBase.h>

#include <CoreGraphics/CGAffineTransform.h>
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGColor.h>
#include <CoreGraphics/CGColorConversionInfo.h>
#include <CoreGraphics/CGColorSpace.h>
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGDataConsumer.h>
#include <CoreGraphics/CGDataProvider.h>
#include <CoreGraphics/CGError.h>
#include <CoreGraphics/CGFont.h>
#include <CoreGraphics/CGFunction.h>
#include <CoreGraphics/CGGeometry.h>
#include <CoreGraphics/CGGradient.h>
#include <CoreGraphics/CGImage.h>
#include <CoreGraphics/CGLayer.h>
#include <CoreGraphics/CGPDFArray.h>
#include <CoreGraphics/CGPDFContentStream.h>
#include <CoreGraphics/CGPDFContext.h>
#include <CoreGraphics/CGPDFDictionary.h>
#include <CoreGraphics/CGPDFDocument.h>
#include <CoreGraphics/CGPDFObject.h>
#include <CoreGraphics/CGPDFOperatorTable.h>
#include <CoreGraphics/CGPDFPage.h>
#include <CoreGraphics/CGPDFScanner.h>
#include <CoreGraphics/CGPDFStream.h>
#include <CoreGraphics/CGPDFString.h>
#include <CoreGraphics/CGPath.h>
#include <CoreGraphics/CGPattern.h>
#include <CoreGraphics/CGShading.h>

#endif  /* COREGRAPHICS_H_ */

使用這些文件時必須顯式的引用。

#import <CoreGraphics/CoreGraphics.h>

框架的應用

1. 幾個應用方向

這個框架主要應用的方向其實就是繪制自定義視圖,幾個具有代表性的方向:

  • 繪制文字
  • 根據(jù)任意路徑繪制圖像
  • 繪制漸變色
  • 抗鋸齒渲染

2. 幾個專業(yè)術語

還需要注意下面幾個專業(yè)術語:

  • 路徑 path
  • 陰影 shadow
  • 筆畫 stroke
  • 剪裁路徑 Clip Path
  • 線條粗細 Line Width
  • 混合模式Blend Mode
  • 填充色 Fill Color
  • 當前形變矩陣Current Transform Matrix
  • 線條圖案Line Dash

3. 幾個重要概念

上下文 Context

這個是繪圖中最重要的概念,相當于我們畫圖的畫布,我們可以簡單地給Quartz繪圖序列指定不同的Graphics Context,就可將相同的圖像繪制到不同的設備上。而不需要任何設備相關的計算,這些都由Quartz替我們完成。

我們還可以從下面角度理解上下文。

  • 一個Graphics Context表示一個繪制目標。它包含繪制系統(tǒng)用于完成繪制指令的繪制參數(shù)和設備相關信息。
  • Graphics Context定義了基本的繪制屬性,如顏色、裁減區(qū)域、線條寬度和樣式信息、字體信息、混合模式等。
  • iOS應用程序中,如果要在屏幕上進行繪制,需要創(chuàng)建一個UIView對象,并實現(xiàn)它的drawRect:方法。視圖的drawRect:方法在視圖顯示在屏幕上及它的內容需要更新時被調用,通過調用UIGraphicsGetCurrentContext()方法可以獲取當前的Graphics Context。
  • Quartz2D的坐標系統(tǒng)原點是左下角,UI控件的坐標系統(tǒng)原點是左上角,如果繪圖的上下文,是使用UIGraphicsGetCurrentContext或者其他以UI開頭的方法獲取到的,在繪圖時無需進行坐標轉換。

主要有下面幾種上下文:

  • Bitmap Graphics Context
  • PDF Graphics Context
  • Window Graphics Context
  • Layer Graphics Context
  • Printer Graphics Context

4. 框架架構及原理

下面看一下ios圖像處理模塊的經(jīng)典原理配圖。

ios圖像處理

最上層是UIKit框架,這是服務于Application的最前端框架,封裝了所有控件類和操作;在其之下是Core Animation框架,借助與這個框架,Apple向開發(fā)人員提供了非常方便的動畫處理功能和圖像渲染功能。再往下,分離成基于GPU繪圖的OpenGL ES層和基于CPU繪圖的Core Graphic層。最底層的就是支持最終繪圖的硬件平臺,包括GPU,CPU,緩存,總線等等。

下面看一下CoreAnimation渲染。

CoreAnimation渲染

這里雖然畫著是他們都具有很明顯的分隔,但是實際上他們的應用是十分緊密的,可以看一下下面的原理圖。

工作原理圖

這里可以看見,CPUGPU都可以繪圖,不過最終都是送到GPU進行顯示了。

CPU和GPU工作關系

下面看幾個容易混淆的概念CoreGraphics、QuartzCoreQuartz。

  • CoreGraphics.framework

    • Quartz 2D : API manages the graphic context and implements drawing.
    • Quartz Services : API provides low level access to the window server. This includes display hardware, resolution, refresh rate, and others.
  • QuartzCore.framework

    • Core Animation : Objective-C API to do 2D animation.
    • Core Image: image and video processing (filters, warp, transitions).iOS 5
  • Quartz.framework (OS X only)

    • Image Kit: display and edit images.
    • PDF Kit: display and edit PDFs.
    • Quartz Composer: display Quartz Composer compositions.
    • QuickLookUI: preview media elements.
  • 其它一些Quartz技術:

    • Quartz Extreme: GPU acceleration for Quartz Composer.
    • QuartzGL (aka "Quartz 2D Extreme"): GPU acceleration for Quartz 2D.

5. 幾個重要的問題

Quartz2D坐標轉換

  • CGContextRotateCTM(CGContextRef c, CGFloat angle)方法可以相對原點旋轉上下文坐標系。
    -CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)方法可以相對原點平移上下文坐標系。
  • CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)方法可以縮放上下文坐標系。

注意:

  • 轉換坐標系前,使用CGContextSaveGState(CGContextRef c)保存當前上下文狀態(tài)。
  • 坐標系轉換后,使用CGContextRestoreGState(CGContextRef c)可以恢復之前保存的上下文狀態(tài)。

drawRect:方法注意事項

  • 是在UIViewControllerloadViewviewDidLoad兩方法之后調用的。
  • 如果在UIView初始化時沒有設置CGRectdrawRect:將不會被自動調用。
  • 如果設置UIView的contentMode屬性值為UIViewContentModeRedraw,那么將在每次更改frame時自動調用drawRect:。
  • 如果使用UIView繪圖,只能在drawRect:方法中獲取相應的CGContextRef并繪圖。而在其他方法中獲取的CGContextRef不能用于繪圖。
  • 重繪時應該調用setNeedsDisplay,而不能直接調用drawRect:setNeedsDisplay會自動調用drawRect:。

內存管理問題

  • Quartz2D是C語言的框架,并且部分需要自己管理內存,使用含CreateCopy的函數(shù)創(chuàng)建的對象,使用完后必須釋放,否則將導致內存泄露。
  • 使用不含有CreateCopy的函數(shù)獲取的對象,則不需要釋放。
  • 如果retain了一個對象,不再使用時,需要將其release掉??梢允褂?code>Quartz 2D的函數(shù)來指定retain和release一個對象。例如,如果創(chuàng)建了一個CGColorSpace對象,則使用函數(shù)CGColorSpaceRetainCGColorSpaceRelease來retain和release對象。也可以使用 Core FoundationCFRetainCFRelease。注意不能傳遞NULL值給這些函數(shù)。

參考文章

1. iOS 2D Graphic(1)—— Concept 基本概念和原理
2. 整理一下CoreGraphic和Quartz2D的知識(一)

后記

未完,待續(xù)~~~

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容