Quartz 2D Programming Guide

本文详细介绍了CoreGraphics在iOS中的应用,包括上下文状态管理、抗锯齿设置、路径绘制、混合模式设置等内容。并提供了如何创建路径、填充路径、设置图案填充等实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Graphics States

<wbr>在创建context的时候,都会创建一个空的stack用于存储graphics的状态。通过函数CGContextSaveGState和函数CGContextRestoreGState分别将graphics的状态压入和弹出stack。<br><wbr> graphics的状态不好看path,path数据不会存在stack中。<br><br><span style="font-weight:bold">Drawing to a View Graphics Contextin iOS</span><br><br><wbr>在iOS中绘画是在UIView中通过UIView的函数drawRect:来实现的。drawRect:函数在view在当前的屏幕上可见并且view的部分需要更新的时候才会被调用。<br><wbr> 注意:<br><wbr>1、drawRect:函数并不会自动被调用,一般在view可见的情况下,加载view的时候被调用一次,之后如果需要调用需要调用view的函数setNeedsDisplay或setNeedsDisplayRect(函数名忘了)的时候才会被调用。<br><wbr>2、调用drawRect:的时候,系统会自动的对绘画的环境进行设置,其中包括为当前的UIView建立一个context,也就是说在drawRect:函数外调用UIGraphicsGetCurrtentCon<wbr>text函数,无法获取当前的context<br><wbr> 3、Quartz是core graphics的总称,跟coregraphics采用的坐标系为LLO,UIView采用的是UIKit框架坐标轴为ULO,变换的时候通过CTM<br><br><span style="font-weight:bold">Anti-Aliasing(消除锯齿)</span><br><br><wbr> 消除锯齿的工作需要两步骤:<br><wbr> 1、将graphicscontext的状态设置为anti-aliasing。通过函数CGContextSetShouldAntial<wbr>ias<br><wbr>2、将context设置为anti-aliasing。通过函数CGContextSetAllowsAntial<wbr>iasing。true:allowinganti-aliasing; false: not to allow it。<br><br><span style="font-weight:bold">Creating a Path</span><br><br><wbr>在一个context中绘画,通过函数CGContextBeginPath开始。之后通过函数CGcontextMoveToPoint设置第一个点,在之后通过CGContextAddLine等函数添加更多的图形,最后通过fill或stroke函数将path画在context上。<br><wbr>例如:CGContextDrawPath(contextRef,kCGPathStroke)或CGContextStrokePath(context)<br><wbr> 注意:<br><wbr> 1、之前的一系列函数仅仅是构造path,并没有将path画在context上。<br><wbr>2、调用CGContextClip之前,path是不能fill或者stoke的,否则出不来clip的效果<br><wbr>与context构造path对应的,还可以通过CGPathRef的函数构造path,原理是相同的。画path的时候调用CGContextAddPath。<br><wbr>具体的path的参数请参考原文:https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_paths/dq_paths.html<br><wbr> 例如:画虚线,可以通过CGContextSetLineDash完成。<br><wbr>除此之外,画矩形、椭圆、线段还有一些更直接的函数,不需要先add,在stroke,可以直接调用下面的函数:<br><wbr> CGContextStrokePath<br><wbr> CGContextStrokeRect<br><wbr> CGContextStrokeRectWithW<wbr>idth<br><wbr> CGContextStrokeEllipseIn<wbr>Rect<br><wbr> CGContextStrokeLineSegme<wbr>nts(参数的形式:线段一起始点,线段一结束点,线段二起始点,线段二结束点···)<br><br><span style="font-weight:bold">Filling a Path</span><br><wbr> 此部分与上一部分差不多,直接参考原文。<br><br><span style="font-weight:bold">Setting Blend Modes</span><br><br><wbr> Blendmodes表示的是在一个背景上画画的时候,前后颜色是如何叠加的。正常情况下,绘图时Qutarz采用的时候默认的模式,显现的效果是通过下面的计算得到的:<br> result = (alpha * foreground) + (1 - alpha) * background<br><wbr> blend modes属于contextstates,可以通过CGContextSaveGState和CGContextRestoreGState在stack中保存和推出context的states。设置blendmode的方法是CGContextSetBlendMode。<br><br><span style="font-weight:bold">Clipping to a Path</span><br><br><wbr>此部分的意义在于将path作为mask来用,通过两个函数:CGContextClip和函数CGContextDrawImage,实现path经过的部分的图片被显现出来,未经过的部分则不显示。<br><wbr>此处与画线的不同之处在于用CGContextClip代替了画线的fill和stroke<br><br><span style="font-weight:bold">Transforms</span><br><br><wbr> 第一种方法:通过CTM<br><wbr> CGContextTranslateCTM<br><wbr> CGContextScaleCTM:x,y有负值,就代表了反方向<br><wbr> CGContextRotateCTM:-值代表了顺时针,正值代表了逆时针。弧度制<br><wbr> 其他方法原理相似,参考源文档<br><br><span style="font-weight:bold">Pattern</span><br><br><wbr> pattern在我看来就是图样、或叫模板。主要作用是设置context的fill或者strokepattern之后,context中调用fill或者stroke的时候用该pattern填充。<br><wbr> 首先,pattern分为两种:带色和不带色的。它们两个的区别主要体现在一下几个方面:<br><wbr> 1、建立callbackfunction的时候。color:指出fill或者stroke的颜色。stencil:不指出颜色,直接调用fill和stroke建立对应的cell,建立color的时候需要指出使用RGB的colorspace,这样方便后面用rgb对pattern着色。当然,针对color的pattern,完全可以采用一个图片来作为patterncell,那么直接将这个图片画在context就算是建立cell了,具体代码在后。<br><wbr> 2、color space的时候,stencile:指出color为RGB colorspace<br><wbr>3、设置采用当前的pattern填充的时候,调用CGContextSetFillPattern或者CGContextSetStrokePatter<wbr>n,对于stencile,需要指出采用的颜色的RGB值,意在着色。<br><wbr>4、在patterncreate,isColored设置为false对于stencile<br><wbr> 两种pattern使用的时候都是分为一下5个步骤:<br><wbr> 1、write a callback function that draw a coloredpattern cell<br><wbr> 2、set up the colored pattern color space<br><wbr> 3、set up the anatomy of the coloredpattern<br><wbr> 4、specify the colored pattern as a fill orstroke pattern<br><wbr> 5、draw with the colored pattern<br> 代码示例:<br> color:<br> void MyPatternDraw(void *info,CGContextRef contextRef)//1、patterncell callback function<br> {<br><wbr><wbr><wbr> UIImage*image = [UIImage imageNamed:@"2.png"];<br><wbr><wbr><wbr> CGImageRefimageRef = image.CGImage;<br><wbr><wbr><wbr> CGRect rect= CGRectMake(0, 0, CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));<br><wbr><wbr><wbr><br><wbr><wbr><wbr>CGContextDrawImage(contextRef, rect, imageRef);<br> }<br> void MyColoredPatternDraw(CGContextRef contextRef,CGRectrect)//2,3,4,5<br> {<br><wbr><wbr><wbr> CGPatternRefpatternRef;<br><wbr><wbr><wbr>CGColorSpaceRef patternSpace;<br><wbr><wbr><wbr> float alpha= 1;<br><wbr><wbr><wbr> static constCGPatternCallbacks callbacks ={0,&amp;MyPatternDraw,NULL};//参数:版本,开始话pattern的函数和最后释放空间的函数<br><wbr><wbr><wbr><br><wbr><wbr><wbr>CGContextSaveGState(contextRef);<br><wbr><wbr><wbr> patternSpace=CGColorSpaceCreatePatter<wbr>n(NULL);//这里为null,若为stencile,需简历一个rgb的colorspace,并作为这个函数的参数<br><wbr><wbr><wbr>CGContextSetFillColorSpa<wbr>ce(contextRef, patternSpace);<br><wbr><wbr><wbr>CGColorSpaceRelease(patternSpace);<br><wbr><wbr><wbr><br><wbr><wbr><wbr> patternRef =CGPatternCreate(NULL,<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>CGRectMake(0, 0, 41, 50), //pattern 的大小<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>CGAffineTransformMakeSca<wbr>le(1, -1),//通过这个可以对单个cell进行旋转,放大、缩小操作<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>60, 60,//pattern之间的上下间隔<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>kCGPatternTilingConstant<wbr>Spacing,<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
资源下载链接为: https://pan.quark.cn/s/502b0f9d0e26 在进行STM32F103C8T6与HC - 06蓝牙模块、PC端以及ROS(机器人操作系统)的串口通信测试时,我们编写了以下程序。 硬件连接 将STM32F103C8T6的USART1的TX(PA9)引脚与HC - 06的RX引脚相连,同时将USART1的RX(PA10)引脚与HC - 06的TX引脚相连,以实现两者之间的串口通信。 另外,通过串口转USB模块(如CH340等)将STM32F103C8T6与PC端连接起来,方便在PC端进行通信数据的发送和接收。 程序功能 初始化USART1,设置波特率为9600,用于与HC - 06通信。同时,初始化USART2(连接串口转USB模块),波特率同样设置为9600,用于与PC端通信。 在主循环中,STM32F103C8T6不断检测USART1和USART2是否有数据接收。当从USART1(HC - 06)接收到数据时,将数据暂存到一个缓冲区中,然后通过USART2发送给PC端。反之,当从USART2(PC端)接收到数据时,也暂存到缓冲区,再通过USART1发送给HC - 06。这样就实现了STM32F103C8T6作为中间节点,将HC - 06与PC端的数据进行转发。 硬件连接 HC - 06蓝牙模块通过串口与STM32F103C8T6连接,如上所述。 程序功能(蓝牙通信部分) HC - 06在默认状态下会自动进入配对模式,等待与手机或其他蓝牙设备配对。当配对成功后,它会将从蓝牙设备接收到的数据通过串口发送给STM32F103C8T6。同时,它也会将STM32F103C8T6发送过来的数据转发给已配对的蓝牙设备。在本测试程序中,主要关注其与STM32F103C8T6之间的串口通信功能,确保数据能够正确地在两者之间传输。 硬件连接 通过串口
内容概要:本文详细介绍了一个基于两个单片机串行通信的电子密码锁项目。项目背景指出随着信息技术的发展,电子密码锁因其高可靠性、低成本等优势成为主流选择。项目采用主控和辅助两个单片机分别负责不同功能模块,并通过串行通信(如UART协议)实现数据交互。主控单片机处理密码输入验证、用户界面显示等,辅助单片机负责锁控制。系统还涉及多级安全防护、低功耗设计、友好的用户界面等特性。项目挑战包括确保通信稳定、提升密码验证安全性、优化电源管理和用户交互设计等。项目创新点在于双单片机协同工作、串行通信协议优化、多级安全防护以及低功耗设计。; 适合人群:对嵌入式系统开发有一定了解,特别是对单片机编程、串行通信协议、密码锁设计感兴趣的工程师或学生。; 使用场景及目标:①适用于家庭安防、商业办公、银行金融、智能酒店、医疗行业等需要高安全性的场所;②帮助开发者掌握双单片机协同工作的原理,提高系统的稳定性和安全性;③通过实际项目加深对串行通信协议的理解,掌握密码锁系统的软硬件设计方法。; 阅读建议:建议读者结合实际硬件设备进行实践操作,重点理解串行通信协议的设计与实现,同时关注密码验证的安全性设计和电源管理优化。此外,可以通过提供的代码示例加深对各功能模块的理解,并尝试修改和优化代码以适应不同的应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值