你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS Quartz 2D繪圖知識詳解

iOS Quartz 2D繪圖知識詳解

編輯:IOS開發綜合

* Quartz*
1. Mac OS X的Darwin核心之上的繪圖層,有時候也認為是CoreGraphics。共有兩種部分組成Quartz:
2. Quartz Compositor,合成視窗系統,管理和合成幕後視窗影像來建立Mac OS X使用者接口。
3. Quartz 2D,是iOS和Mac OS X環境下的二維繪圖引擎。
涉及內容包括:基於路徑的繪圖,透明度繪圖,遮蓋,陰影,透明層,顏色管理,防鋸齒渲染,生成PDF,以及PDF元數據相關處理。

*一、Quartz 2D的簡單介紹**
1. Quartz 2D屬於Core Graphics(所以大多數相關方法的都是以CG開頭),是iOS/Mac OSX 提供的在內核之上的強大的2D繪圖引擎,並且這個繪圖引擎是設備無關的。也就是說,不用關心設備的大小,設備的分辨率,只要利用Quartz 2D,這些設備相關的會自動處理。
**2.**Quartz 2D能夠提供的強大功能如下:

1. 透明層(transparency layers) 
2. 陰影 基於path的繪圖(path-based drawing)
3. 離屏渲染(offscreen rendering) 
4. 復雜的顏色處理(advanced color management) 
5. 抗鋸齒渲染(anti-aliased rendering)
6. PDF創建,展示,解析(這部分不在這個系列之中) 配合Core Animation, OpenGL ES,UIKit完成復雜的功能 畫板-The Graphics Context
7. 而Quartz 2D的容器就是CGContextRef數據模型。這種數據模型是C的結構體,存儲了渲染到屏幕上需要的一切信息。

二、Quartz 2D詳解:

Quartz 2D的基本數據類型:
Quartz 2D中的數據類型都是透明的,也就是說用戶只需要使用即可,不需要實際訪問其中的變量。具體的數據類型包括

1. CGPathRef 路徑類型,用來繪制路徑(注意帶有ref後綴的一般都是繪制的畫板)
2. CGImageRef,繪制bitmap
3. CGLayerRef,繪制layer,layer可復用,可離屏渲染
4. CGPatternRef,重復繪制
5. CGShadingRef和CGGradientRef,繪制漸變(例如顏色漸變)
6. CGFunctionRef,定義回調函數,CGShadingRef和CGGradientRef的輔助類型
7. CGColorRef and CGColorSpaceRef,定義如何處理顏色
8. CGFontRef,繪制文字

Quartz 2D的坐標

UIKit默認的坐標系統與Quartz不同。在UIKit中,原點位於左上角,y軸正方向為向下。UIView通過將修改Quartz的Graphics Context的CTM[原點平移到左下角,同時將y軸反轉(y值乘以-1)]以使其與UIView匹配。這些都是系統自動幫我們完成。

三、直線/矩形

基本圖形繪制需要的屬性

1.獲取當前上下文(context)(UIGraphicsGetCurrentContext)
2.設置顏色:
    CGContextSetFillColorWithColor:設置描邊顏色
    CGContextSetFillColorWithColor:設置填充顏色
3. 畫的范圍
    CGContextStrokeRect:描邊的范圍
    CGContextFillRect:填充的范圍
4.CGContextSetLineWidth:線寬
5.CGContextSetLineCap:線頂端的樣式
6.CGContextSetLineJoin:線拐角的樣式
7. 線的起始點:
    CGContextMoveToPoint:起點 
    CGContextAddLineToPoint:終點
8.CGContextFillPath :填充的路徑
9.CGContextStrokePath:描邊的路徑

直線、矩形 demo

- (void)drawRect:(CGRect)rect {

    //1.獲得當前context
    CGContextRef context = UIGraphicsGetCurrentContext();

    //設置顏色 (填充色和 描邊的顏色)
    CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.8 alpha:1].CGColor);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);

    //設置描邊線寬
    CGContextSetLineWidth(context, 20);

    //對矩形進行填色  或  描邊
    //(注意:如果先描邊再填充,由於矩形大小一致,那麼描邊的線就會被填充的矩形擋住)
    CGContextFillRect(context, rect);
    CGContextStrokeRect(context, rect);

    //-----------------------------------------------------------------

    //MARK: ------ 實際line和point的代碼
    // 設置描邊顏色
    CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);    CGContextSetLineWidth(context, 8.0);//線的寬度
    CGContextSetLineCap(context, kCGLineCapRound);//線的頂端
    CGContextSetLineJoin(context, kCGLineJoinRound);//線相交的模式

    //-----------------------------------------------------------------
    //MARK:黃色的  ">" 圖形
    //移動畫筆到哪個點
    CGContextMoveToPoint(context,20,20);
    //畫筆畫到哪個點
    CGContextAddLineToPoint(context, rect.size.width - 20, rect.size.height / 2 - 20);
    CGContextAddLineToPoint(context, 20, rect.size.height - 20);
    //根據上下文中的點,成線進行描邊
    CGContextStrokePath(context);

    //------------------------------------------------------------------
    //MARK: 紅色的小的三角的填充
    CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
    CGContextMoveToPoint(context, 0, rect.size.height / 2 - 30);
    CGContextAddLineToPoint(context, 30, rect.size.height / 2);
    CGContextAddLineToPoint(context, 0, rect.size.height / 2 + 30);
    CGContextFillPath(context);
   //虛線效果
  //CGContextSetLineDash(context, 1, lengths, 1);

 //------------------------------------------------------------------
    //MARK: 紅色虛線效果
    CGContextSetStrokeColorWithColor(context,[UIColor redColor].CGColor);
    CGContextSetLineWidth(context, 1);

    CGContextMoveToPoint(context, rect.size.width - 20, 20);
    CGContextAddLineToPoint(context, rect.size.height - 20, rect.size.width - 20);
    CGFloat lengths[] = {20};
    CGContextSetLineDash(context, 1, lengths, 1);
    CGContextStrokePath(context);
}

運行之後的效果:

\

虛線效果

CGContextSetLineDash參數詳解
void CGContextSetLineDash (
CGContextRef _Nullable c,
CGFloat phase,
const CGFloat * _Nullable lengths,
size_t count
);
c 繪制的context,這個不用多說
phase,第一個虛線段從哪裡開始,例如傳入3,則從第三個單位開始
lengths,一個C數組,表示繪制部分和空白部分的分配。例如傳入[2,2],則繪制2個單位,然後空白兩個單位,以此重復
count lengths的數量

四、曲線— 圓弧的繪制

Quartz提供了兩個方法來繪制圓弧
1. CGContextAddArc,普通的圓弧一部分(以某圓心,某半徑,某弧度的圓弧)
2. CGContextAddArcToPoint,用來繪制圓角

 


CGContextAddArc

 

結構:
void CGContextAddArc (
CGContextRef _Nullable c,
CGFloat x, // 圓心X坐標
CGFloat y, // 圓心Y坐標
CGFloat radius, // 弧度半徑
CGFloat startAngle, // 開始的弧度
CGFloat endAngle, // 結束的弧度
int clockwise //1表示順時針,0表示逆時針
);
- (void)drawRect:(CGRect)rect {
    //--------------------------------------------------------------------
    //MARK: 畫弧
    //1.獲取圖片上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    //2.設置弧度及位置
     //根據中心點,半徑,起始的弧度,最後的弧度,是否順時針畫一個圓弧
    CGContextAddArc(context, rect.size.width / 2, rect.size.height / 2, 20, M_PI_4, M_PI, 1);
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    //3.畫
    CGContextDrawPath(context, kCGPathStroke);

    // -----------------------------------------------------

    //MARK:畫有線圈的圓餅
    CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);//設置線的顏色
    CGContextSetRGBFillColor(context, 0, 0, 1, 1);//設置填充顏色
    CGContextSetLineWidth(context, 2); //設置線的寬度
    CGContextAddEllipseInRect(context, CGRectMake(10, 30, 60, 60)); //畫一個橢圓或者圓
    CGContextDrawPath(context, kCGPathFillStroke);
}

\

2.CGContextAddArcToPoint

void CGContextAddArcToPoint (
CGContextRef _Nullable c,
CGFloat x1,
CGFloat y1,
CGFloat x2,
CGFloat y2,
CGFloat radius
);
c context x1,y1和當前點(x0,y0)決定了第一條切線(x0,y0)->(x1,y1) x2,y2和(x1,y1)決定了第二條切線 radius,想切的半徑。
也就是說,
繪制一個半徑為radius的圓弧,和上述 兩條直線都相切。

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);//設置線的顏色
    CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);//設置填充顏色
    CGContextSetLineWidth(ctx, 2); //設置線的寬度

    //CGContextAddArcToPoint 先要確定三個點,
    //1.從哪裡開始劃線 CGContextMoveToPoint (也就是兩條線的交點)
    //2.第二個點與起始點  確定一條直線
    //3.第三個點與第二個點  確定另外一條直線

    //畫一個圓角矩形
    //確定矩形的位置和大小
    CGRect rrect = CGRectMake(rect.size.width / 2 - 30, rect.size.height / 2 - 30, 60.0, 60.0);

    CGFloat radius = 15.0;//半徑,半徑為正方形一半時,那就可以切成圓形

    CGFloat
    minx = CGRectGetMinX(rrect),//矩形中最小的x
    midx = CGRectGetMidX(rrect),//矩形中最大x值的一半
    maxx = CGRectGetMaxX(rrect);//矩形中最大的x值

    CGFloat
    miny = CGRectGetMinY(rrect),//矩形中最小的Y值
    midy = CGRectGetMidY(rrect),//矩形中最大Y值的一半
    maxy = CGRectGetMaxY(rrect);//矩形中最大的Y值


    CGContextMoveToPoint(ctx, minx, midy);//從點A 開始
    //從點A到點B再從點B到點C形成夾角進行切圓
    CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius);
    CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius);
    CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius);
    CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius);
    CGContextClosePath(ctx);
    CGContextDrawPath(ctx, kCGPathFillStroke);
}

運行效果:

\

貝塞爾曲線

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetLineWidth(context, 4);


    CGFloat
    minx = CGRectGetMinX(rect),//矩形中最小的x
    midx = CGRectGetMidX(rect),//矩形中最大x值的一半
    maxx = CGRectGetMaxX(rect);//矩形中最大的x值

    CGFloat
    miny = CGRectGetMinY(rect),//矩形中最小的Y值
    midy = CGRectGetMidY(rect),//矩形中最大Y值的一半
    maxy = CGRectGetMaxY(rect);//矩形中最大的Y值

    //貝塞爾曲線一,兩個控制點 紅色
    CGPoint s = CGPointMake(minx + 10, miny + 10); //起始點
    CGPoint e = CGPointMake(maxx - 10, maxy - 10);//終點
    CGPoint cp1 = CGPointMake(miny, midy);//控制點1
    CGPoint cp2 = CGPointMake(midy, minx);//控制點2
    CGContextMoveToPoint(context, s.x, s.y);
    CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);
    CGContextStrokePath(context);

    //貝塞爾曲線二,一個控制點 藍色
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    s = CGPointMake(minx, maxy);
    e = CGPointMake(maxx, maxy);
    cp1 = CGPointMake(midx, midy);
    CGContextMoveToPoint(context, s.x, s.y);
    CGContextAddQuadCurveToPoint(context, cp1.x, cp1.y, e.x, e.y);
    CGContextStrokePath(context);
}

運行效果

\

五、顏色漸變
demo

- (void)drawRect:(CGRect)rect {
    // Drawing code

    // 創建Quartz上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 創建色彩空間對象
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    // 創建起點顏色
    CGColorRef beginColor = CGColorCreate(colorSpaceRef, (CGFloat[]){0.01f, 0.5f, 0.01f, 1.0f});

    // 創建終點顏色
    CGColorRef endColor = CGColorCreate(colorSpaceRef, (CGFloat[]){0.99f, 0.99f, 0.01f, 1.0f});

    // 創建顏色數組
    const void **values = (const void*[]){beginColor, endColor};//顏色數組
    CFArrayRef colorArray = CFArrayCreate(
                                          kCFAllocatorDefault,
                                          values,//顏色數組
                                          2,//數組的個數
                                          nil// CGGradientCreateWithColors的最後一個locations參數可以傳空,這樣默認為從0.0到1.0。
                                          );

    // 創建漸變對象
    CGGradientRef gradientRef = CGGradientCreateWithColors(colorSpaceRef, colorArray, (CGFloat[]){
        0.0f,       // 對應起點顏色位置
        1.0f        // 對應終點顏色位置
    });

    // 釋放顏色數組
    CFRelease(colorArray);

    // 釋放起點和終點顏色
    CGColorRelease(beginColor);
    CGColorRelease(endColor);

    // 釋放色彩空間
    CGColorSpaceRelease(colorSpaceRef);

    /*
     1.context          上線文
     2.gradientRef      顏色數組
     3.startPoint       開始位置
     4.endPoint         結束位置
     5.CGGradientDrawingOptions         
     當你的起點或者終點不在圖形上下文的邊緣內時,指定該如何處理。你可以使用你的開始或結束顏色來填充漸變以外的空間。此參數為以下值之一:
     KCGGradientDrawsAfterEndLocation擴展整個漸變到漸變的終點之後的所有點 
     KCGGradientDrawsBeforeStartLocation擴展整個漸變到漸變的起點之前的所有點。
     0不擴展該漸變。
     */
    CGPoint startPoint = CGPointMake(0.0f, 0.0f);
    CGPoint endPoint = CGPointMake(rect.size.width, rect.size.height);
    CGGradientDrawingOptions options = kCGGradientDrawsAfterEndLocation;
    CGContextDrawLinearGradient(
                                context,
                                gradientRef,
                                startPoint,
                                endPoint,
                                kCGGradientDrawsBeforeStartLocation
//                                kCGGradientDrawsAfterEndLocation
                                );


    // 釋放漸變對象
    CGGradientRelease(gradientRef);
}

效果圖
\

六、多中顏色的渲染
demo

- (void)drawRect:(CGRect)rect {
    // 創建Quartz上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 創建色彩空間對象
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    // 創建漸變對象
    CGGradientRef gradientRef =
    CGGradientCreateWithColorComponents(colorSpaceRef,
                                        (CGFloat[]){
                                         1.0f,0.8f,0.5f,1.0f,//第一個顏色RGB 和透明度
                                         0.6f,0.5f,0.6f,1.0f,//第二個顏色RGB 和透明度
                                         0.3f,0.2f,0.f,1.0f,//第三個顏色RGB 和透明度
                                         .0f,0.0f,0.3f,1.0f
                                        },
                                        (CGFloat[]){  0.0f,0.3f,.6f,1},//顏色漸變的位置
                                        4);//顏色的個數

    // 釋放色彩空間
    CGColorSpaceRelease(colorSpaceRef);

    // 填充漸變色
    CGContextDrawLinearGradient(context, gradientRef, CGPointMake(0.0f, 0.0f), CGPointMake(320.0f, 460.0f), 0);

    // 釋放漸變對象
    CGGradientRelease(gradientRef);
}

效果
\

幾何圖形繪制屬性—詳解
1.Graphics Context(圖層上下文)

Graphics Context
其實就是表示了一個繪制目標,也就是你打算繪制的地方,它包含繪制系統用於完成繪制指令的繪制參數和設備相關信息。Graphics Context定義了基本的繪制屬性,如顏色、裁減區域、線條寬度和樣式信息、字體信息、混合模式等。 *獲取Graphics Context:
1. Quartz提供的創建函數、Mac OS X框架或IOS的UIKit框架提供的函數。Quartz提供了多種Graphics Context的創建函數,包括bitmap和PDF,我們可以使用這些Graphics Context創建自定義的內容。
2. 在代碼中,我們用CGContextRef來表示一個Graphics Context。當獲得一個Graphics Context後,可以使用Quartz 2D函數在上下文(context)中進行繪制、完成操作(如平移)、修改圖形狀態參數(如線寬和填充顏色)等。

 

 





  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved