iOS 2D繪圖詳解(Quartz 2D)之路徑(stroke,fill,clip,subpath,blend)

來源:互聯網
上載者:User

標籤:

Stroke-描邊

影響描邊的因素

  • 線的寬度-CGContextSetLineWidth
  • 交叉線的處理方式-CGContextSetLineJoin
  • 線頂端的處理方式-CGContextSetLineCap
  • 進一步限制交叉線的處理方式 -CGContextSetMiterLimit
  • 是否要虛線-Line dash pattern
  • 顏色控制項-CGContextSetStrokeColorSpace
  • 畫筆顏色-CGContextSetStrokeColor/CGContextSetStrokeColorWithColor
  • 描邊模式-CGContextSetStrokePattern

虛線,畫筆顏色,交叉的處理方式,頂端的處理方式,線寬度在之前這篇文章裡有講過,這裡不再贅述。

CGContextSetMiterLimit

如果當前交叉線繪圖模式是kCGLineJoinMiter( CGContextSetLineJoin),quartz根據設定的miter值來判斷線的join是bevel或者miter。具體的模式是:將miter的長度除以線的寬度,如果小於設定的mitetLimit值,則join style為bevel;

先看看三種join效果

舉個例子就懂了

    CGContextMoveToPoint(context,10,10);    CGContextAddLineToPoint(context, 50, 50);    CGContextAddLineToPoint(context, 10, 90);    CGContextSetLineWidth(context, 10.0);    CGContextSetLineJoin(context, kCGLineJoinMiter);    CGContextSetMiterLimit(context,20.0);    CGContextStrokePath(context);

效果

將Miter設定為1,則效果如下

CGContextSetStrokeColorSpace和pattern會在以後的文章詳細闡述,這裡暫時先略去

Fill-填充

Quartz填充的時候會認為subpath是封閉的,然後根據規則來填充。有兩種規則:

nonzero winding number rule.沿著當前點,畫一條直線到地區外,檢查交叉點,如果交叉點從左至右,則加一,從右至左,則減去一。如果結果不為0,則繪製。參見這個link

even-odd rule,沿著當前點,花一條線到地區外,然後檢查相交的路徑,偶數則繪製,奇數則不繪製。
具體效果如下

相關函數

  • CGContextEOFillPath - 用even-odd rule來填充
  • CGContextFillPath - 用nonzero winding number rule方式填充
  • CGContextFillRect/CGContextFillRects - 填充指定矩形地區內path
  • CGContextFillEllipseInRect - 填充橢圓
  • CGContextDrawPath - 繪製當前path(根據參數stroke/fill)
Clip-切割

顧名思義,根據path只繪製指定的地區,在地區外的都不會繪製。
舉個例子,截取圓形地區
效果

注意,切割是和狀態相關的,以為這切割以後都是在切割後context中繪製的。
如果要儲存狀態,參照這篇文章裡講的壓棧和出棧

 - (void)drawRect:(CGRect)rect {    CGContextRef context = UIGraphicsGetCurrentContext();    CGContextBeginPath (context);    CGContextAddArc(context,50, 50,20,0, M_PI * 2,true);    CGContextClosePath (context);    CGContextClip (context);    CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);    CGContextFillRect(context, rect);    //New Code    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);    CGContextMoveToPoint(context,10,10);    CGContextAddLineToPoint(context, 50, 50);    CGContextAddLineToPoint(context, 10, 90);    CGContextSetLineWidth(context, 10.0);    CGContextSetLineJoin(context, kCGLineJoinMiter);    CGContextSetMiterLimit(context,20.0);    CGContextStrokePath(context);}-(instancetype)initWithFrame:(CGRect)frame{    if (self = [super initWithFrame:frame]) {        self.opaque = NO;    }    return self;}

相關函數

  • CGContextClip 按照nonzero winding number rule規則切割
  • CGContextEOClip 按照even-odd規則切割
  • CGContextClipToRect 切割到指定矩形
  • CGContextClipToRects 切割到指定矩形組
  • CGContextClipToMask 切割到mask
Subpath - 子路徑

很簡單,在stroke/fill或者CGContextBeginPath/CGContextClosePath以後就新開啟一個子路徑。

注意:

CGContextClosePath,會串連第一個點和最後一個點

Blend-混合模式

Quartz中,預設的顏色混合模式採用如下公式
result = (alpha * foreground) + (1 - alpha) * background

可以使用CGContextSetBlendMode來設定不同的顏色混合模式,注意設定blend是與context繪製狀態相關的,一切與狀態相關的設定都要想到狀態堆棧(如果看不懂這句,看我之前的那兩篇文章裡講的)。

先看看官方文檔裡的例子,最後我會寫個自己的例子
background

foreGround

Normal Blend Mode

效果

Multiply Blend Mode

交叉部分會顯得比較暗,用上一層和底層相乘,至少和一層一樣暗

Screen Blend Mode

交叉部分比較亮,上層的reverse和下層的reverse相乘,至少和一個一樣亮

blend模式較多,這裡不一一列舉了,參見官方文檔

iOS 2D繪圖詳解(Quartz 2D)之路徑(stroke,fill,clip,subpath,blend)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.