博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS学习笔记08-Quartz2D绘图
阅读量:4513 次
发布时间:2019-06-08

本文共 5676 字,大约阅读时间需要 18 分钟。

一、Quartz2D简单介绍

在iOS中常用的绘图框架就是Quartz2DQuartz2DCore Graphics框架的一部分,我们日常开发使用的所有UIKit组件都是由Core Graphics进行绘制的

在iOS中Quartz2D绘图的一般步骤:
  1. 获取绘制上下文
  2. 创建并设置路径
  3. 将路径添加进绘制上下文中
  4. 设置上下文状态
  5. 绘制路径
  6. 释放路径

UIKit默认为我们提供了一个图形上下文,在UI控件的drawRect:方法中调用UIGraphicsGetCurrentContext()获取图形上下文

下面是使用实例,在自定义UIView类内定义:
#pragma mark 绘图   - (void)drawRect:(CGRect)rect{ //绘图只能在此方法中调用,否则无法得到当前图形上下文 //1.取得图形上下文对象 CGContextRef context = UIGraphicsGetCurrentContext(); //2.创建路径对象 CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, nil, 20, 50);//移动到指定位置(设置路径起点) CGPathAddLineToPoint(path, nil, 20, 100);//绘制直线(从起始位置开始) CGPathAddLineToPoint(path, nil, 300, 100);//绘制另外一条直线(从上一直线终点开始绘制) //3.添加路径到图形上下文 CGContextAddPath(context, path); //4.设置图形上下文状态属性 CGContextSetRGBStrokeColor(context, 1.0, 0, 0, 1);//设置笔触颜色 CGContextSetRGBFillColor(context, 0, 1.0, 0, 1);//设置填充色 CGContextSetLineWidth(context, 2.0);//设置线条宽度 CGContextSetLineCap(context, kCGLineCapRound);//设置顶点样式 CGContextSetLineJoin(context, kCGLineJoinRound);//设置连接点样式 /*设置线段样式 CGContextSetLineDash(context, phase, lengths, count); phase:虚线开始的位置 lengths:虚线长度间隔 count:虚线数组元素个数 */ CGFloat lengths[2] = { 18, 9 }; CGContextSetLineDash(context, 0, lengths, 2); /*设置阴影 CGContextSetShadowWithColor(context, offset, blur, color); offset:偏移量 blur:模糊度 color:阴影颜色 */ CGColorRef color = [UIColor grayColor].CGColor;//Quartz2D是跨平台的,使用的是C语言 CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 0.8, color); //5.绘制图像到指定图形上下文 /*填充方式CGPathDrawingMode kCGPathFill:只有填充(非零缠绕数填充),不绘制边框 kCGPathEOFill:奇偶规则填充(多条路径交叉时,奇数交叉填充,偶交叉不填充) kCGPathStroke:只有边框 kCGPathFillStroke:既有边框又有填充 kCGPathEOFillStroke:奇偶填充并绘制边框 */ CGContextDrawPath(context, kCGPathFillStroke);//最后一个参数是填充类型 //6.释放路径对象 CGPathRelease(path); }

上面的绘制过程太过于麻烦,所以苹果为我们封装了一些绘制方法在UIKit框架中

- (void)drawRect:(CGRect)rect{        //1.获得图形上下文        CGContextRef context = UIGraphicsGetCurrentContext(); //2.添加路径(相当于前面创建路径并添加路径到图形上下文两步操作) CGContextMoveToPoint(context, 20, 50); CGContextAddLineToPoint(context, 20, 100); CGContextAddLineToPoint(context, 300, 100); //封闭路径:直接调用路径封闭方法 CGContextClosePath(context); //3.设置图形上下文属性 [[UIColor redColor] setStroke];//设置红色边框 [[UIColor greenColor] setFill];//设置绿色填充 //[[UIColor blueColor] set];//同时设置填充和边框色 //4.绘制路径 CGContextDrawPath(context, kCGPathFillStroke); }

二、基本图形的绘图方法

# 绘制矩形CGContextAddRect(CGContextRef context, CGRect rect); UIRectFill(CGRect rect);//只有填充 UIRectFrame(CGRect rect);//只有边框 # 绘制椭圆 CGContextAddEllipseInRect(CGContextRef context, CGRect rect); # 绘制弧度 /* context:绘制上下文 x:中心点x坐标 y:中心点y坐标 radius:半径 startAngle:起始弧度,0表示圆的最右边开始 endAngle:终止弧度,正值表示顺时针计算 closewise:是否逆时针绘制,0则顺时针绘制 */ CGContextAddArc(CGContextRef context, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int closewise); # 绘制二次贝塞尔曲线 /* context:图形上下文 cpx:控制点x坐标 cpy:控制点y坐标 x:结束点x坐标 y:结束点y坐标 */ CGContextAddQuadCurveToPoint(CGContextRef context, CGFloat cpx, CGFloat cpy, CGFloat x, CGFloat y); # 绘制三次贝塞尔曲线 /* context:图形上下文 cp1x:第一个控制点x坐标 cp1y:第一个控制点y坐标 cp2x:第二个控制点x坐标 cp2y:第二个控制点y坐标 x:结束点x坐标 y:结束点y坐标 */ CGContextAddCurveToPoint(CGContextRef context, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y);

贝塞尔曲线示意图

三、绘制文本和图像

#pragma mark 绘图- (void)drawRect:(CGRect)rect{    //1.获得图形上下文 CGContextRef context = UIGraphicsGetCurrentContext(); [self drawText:context]; [self drawImage:context]; } #pragma mark 绘制文本 - (void)drawText:(CGContextRef)context{ //绘制到指定的区域内容 NSString *str = @"Star Walk is the most beautiful ......sdadasd dsadsa"; CGRect rect = CGRectMake(20, 50, 280, 300); UIFont *font = [UIFont systemFontOfSize:18];//设置字体 UIColor *color = [UIColor redColor];//字体颜色 NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];//段落样式 style.alignment = NSTextAlignmentLeft;//对齐方式 [str drawInRect:rect withAttributes:@{ NSFontAttributeName:font, NSForegroundColorAttributeName:color, NSParagraphStyleAttributeName:style}]; } #pragma mark 绘制图片 - (void)drawImage:(CGContextRef)context{ UIImage *image = [UIImage imageNamed:@"image2.jpg"]; //从某一点开始绘制 [image drawAtPoint:CGPointMake(10, 50)]; //绘制到指定的矩形中,注意如果大小不合适会会进行拉伸,图像会形变 [image drawInRect:CGRectMake(10, 50, 300, 450)]; //平铺绘制 [image drawAsPatternInRect:CGRectMake(0, 0, 320, 568)]; }

实际上还有一些绘图方法,比如渐变填充叠加模式填充模式,但这些东西使用的不多,这里就不细讲了,有兴趣我可能会另外写个笔记针对这些绘图技巧。

可以参考下面效果:
渐变填充效果图

四、图形上下文形变

Quartz2D的坐标系统UIKit并不一样,它的坐标原点在屏幕左下角,UIKit对其进行了转换,坐标原点统一在屏幕左上角

我们也可以对坐标系进行操作:
#pragma mark 图形上下文形变-(void)drawRect:(CGRect rect){    CGContextRef context = UIGraphicsGetCurrentContext(); //保存初始状态 CGContextSaveGState(context); //形变第一步:图形上下文向右平移40 CGContextTranslateCTM(context, 100, 0); //形变第二步:缩放0.8 CGContextScaleCTM(context, 0.8, 0.8); //形变第三步:旋转 CGContextRotateCTM(context, M_PI_4/4); UIImage *image = [UIImage imageNamed:@"photo1.jpg"]; [image drawInRect:CGRectMake(0, 50, 240, 300)]; //恢复到初始状态 CGContextRestoreGState(context); }
  • 设置图形上下文形变之前一定要注意保存上下文的初始状态,在使用完之后进行恢复
  • 在iOS开发中不允许开发者直接调用drawRect:方法,刷新绘制内容需要调用setNeedsDisplay方法。

五、其他绘制上下文

位图上下文:
# 开启位图上下文,没有返回值UIGraphicsBeginImageContext(CGSize size);# 在开启位图上下文和关闭位图上下文之间,使用该方法获取位图上下文 UIGraphicsGetCurrentContext() # 关闭位图上下文,没有返回值 UIGraphicsEndImageContext()
PDF上下文:
# 开启PDF上下文,没有返回值/*     path : 保存路径     bounds : pdf文档大小,如果设置为CGRectZero,则使用默认值:612*792     pageInfo : 页面设置,为nil则不设置任何信息*/UIGraphicsBeginPDFContextToFile(NSString *path, CGRect bounds, NSDictionary *pageInfo); # 在开启PDF上下文和关闭PDF上下文之间,使用该方法获取PDF上下文 UIGraphicsGetCurrentContext() # 关闭PDF上下文,没有返回值 UIGraphicsEndPDFContext()

我们怎么知道我们绘制成功了呢?

对于PDF,我们可以打开看PDF文件
对于位图,我们可以把绘制后的位图保存为图片对象UIImage
# 返回绘制的新图像UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
一个PDF绘制的小技巧,就是PDF的分页
# 开启一个PDF新页,调用了该方法,以后的绘图操作都是在新页上绘制的IGraphicsBeginPDFPage()

转载于:https://www.cnblogs.com/ming1025/p/6064346.html

你可能感兴趣的文章
vue开发的打包配置
查看>>
jquery基础
查看>>
端口作用
查看>>
不同web应用登录方案
查看>>
利用css制作横向和纵向时间轴
查看>>
Generic(泛型)
查看>>
009 如何更好地进行沟通
查看>>
NFC NDEF vcard
查看>>
mininet test
查看>>
OOP
查看>>
找出数组中的重复元素
查看>>
Apache服务器配置
查看>>
ClickOnce清单签名取消后依然读取证书的问题
查看>>
POJ 1083
查看>>
单变量微积分笔记16——定积分的应用1(对数与面积)
查看>>
ACM模板——最短路
查看>>
实验3 分支语句和循环语句(1)
查看>>
JSP页面上添加Fckeditor
查看>>
scrapyd spiderkeeper docker部署
查看>>
Qt教程
查看>>