zoukankan      html  css  js  c++  java
  • iOS学习笔记08 Quartz2D绘图

    ###一、Quartz2D简单介绍 在iOS中常用的绘图框架就是Quartz2DQuartz2DCore Graphics框架的一部分,我们日常开发使用的所有UIKit组件都是由Core Graphics进行绘制的 ######在iOS中Quartz2D绘图的一般步骤:

    1. 获取绘制上下文
    1. 创建并设置路径
    2. 将路径添加进绘制上下文中
    3. 设置上下文状态
    4. 绘制路径
    5. 释放路径

    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()
    复制代码

    凡是“UI”开头的相关绘图函数,都是UIKit对Core Graphics的封装

    转载于:https://juejin.im/post/5b126d88e51d4506af2e7d12

  • 相关阅读:
    SPOJ 694 (后缀数组) Distinct Substrings
    POJ 2774 (后缀数组 最长公共字串) Long Long Message
    POJ 3693 (后缀数组) Maximum repetition substring
    POJ 3261 (后缀数组 二分) Milk Patterns
    UVa 1149 (贪心) Bin Packing
    UVa 12206 (字符串哈希) Stammering Aliens
    UVa 11210 (DFS) Chinese Mahjong
    UVa (BFS) The Monocycle
    UVa 11624 (BFS) Fire!
    HDU 3032 (Nim博弈变形) Nim or not Nim?
  • 原文地址:https://www.cnblogs.com/twodog/p/12136763.html
Copyright © 2011-2022 走看看