当前位置: 首页 > news >正文

iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)

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模式较多,这里不一一列举了,参见官方文档

相关文章:

  • 炉石传说 C# 开发笔记(BS上线尝试)
  • JAVA移动支付微信和支付宝后台代码
  • delphi xe6中如何调用stringtojstring
  • Lua中调用C函数
  • EqualsBuilder和HashCodeBuilder
  • Flash CS 6绘图技巧之锁定填充
  • Rad Studio 10.1 UP1 移动开发 关于编译ANDROID版本
  • 爪哇国新游记之二十二----排序判断重复时间复杂度为2n的位图法
  • SQL Server 存储过程中处理多个查询条件的几种常见写法分析,我们该用那种写法...
  • Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
  • 正则表达式的汉字匹配
  • Apache,Tomcat,Jboss,jetty
  • 【云栖大会】探索企业互联网转型之路
  • Citrix license 服务不能启动
  • Jquery 采用Append进去的节点无法操作 解决办法
  • php的引用
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • Angular4 模板式表单用法以及验证
  • es6要点
  • HTTP中的ETag在移动客户端的应用
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • KMP算法及优化
  • Laravel 实践之路: 数据库迁移与数据填充
  • Linux gpio口使用方法
  • swift基础之_对象 实例方法 对象方法。
  • vue中实现单选
  • 阿里云购买磁盘后挂载
  • 简单实现一个textarea自适应高度
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 前端性能优化--懒加载和预加载
  • 数组大概知多少
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • # Maven错误Error executing Maven
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #WEB前端(HTML属性)
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (js)循环条件满足时终止循环
  • (LeetCode) T14. Longest Common Prefix
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (原)Matlab的svmtrain和svmclassify
  • ./configure,make,make install的作用(转)
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .mysql secret在哪_MySQL如何使用索引
  • .NET Core 2.1路线图
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [20170705]diff比较执行结果的内容.txt
  • [C++] 统计程序耗时
  • [CF]Codeforces Round #551 (Div. 2)
  • [codevs 1296] 营业额统计
  • [ES-5.6.12] x-pack ssl
  • [HTML]Web前端开发技术12(HTML5、CSS3、JavaScript )——喵喵画网页