代码改变世界

iOS,Core Graphics

2017-09-21 15:57  帅不过三秒  阅读(1210)  评论(0编辑  收藏  举报

Core Graphics 

知识补充
1.Core Graphics是基于C语言的一套框架,开发时无法像使用Obj-C一样调用;
2.在Quartz 2D中凡是使用带有“Create”或者“Copy”关键字方法创建的对象,在使用后一定要使用对应的方法释放(由于这个框架基于C语言编写无法自动释放内存);
3.Quartz 2D是跨平台的,因此其中的方法中不能使用UIKit中的对象(UIKit只有iOS可用),例如用到的颜色只能用CGColorRef而不能用UIColor,但是UIKit中提供了对应的转换方法;
4.在C语言中枚举一般以“k”开头,由于Quartz 2D基于C语言开发,所以它也不例外(参数中很多枚举都是k开头的);
5.由于Quartz 2D是Core Graphics的一部分,所以API多数以CG开头;
6.在使用Quartz 2D绘图API中所有以“Ref”结尾对象,在声明时都不必声明为指针类型;
7.在使用Quartz 2D绘图API时,凡是“UI”开头的相关绘图函数,都是UIKit对Core Graphics的封装(主要为了简化绘图操作);

 

  *Quartz 2D

  Quartz 2D是CoreGraphics框架的一部分,是一个强大的二维图像绘制引擎。在UIKit中也有很好的封装和集成,日常开发时所用到的UIKit中的组件都是由CoreGraphics进行绘制,当我们引入UIKit框架时系统会自动引入CoreGraphics框架,UIKit内部还对一些常用的绘图API进行了封装。

  *基本图形绘制

  在UIKit中有一个默认的图形上下文对象,在UI控件的drawRect:方法(这个方法在loadView、viewDidLoad方法后执行)中我们可以通过UIKit封装函数UIGrahicsGetCurrentContext()方法获得这个图形上下文(在其他UI控件方法中无法取得这个对象),自定义一个View继承自UIView,重写drawRect:方法绘制。

//基本绘图,创建一个小三角
-(void)createTriangleBasicView{
    //取得图像上下文对象
    CGContextRef context=UIGraphicsGetCurrentContext();
    //创建路径对象
    CGMutablePathRef path=CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, 20, 50);//移动到指定位置(设置路径起点)
    CGPathAddLineToPoint(path, nil, 20, 100);//绘制直线(从起始位置开始)
    CGPathAddLineToPoint(path, nil, 300, 100);//绘制另外一条直线(从上一直线终点开始绘制)
    //添加到路径图形上下文
    CGContextAddPath(context, path);
    //设置图形上下文状态属性
    CGContextSetRGBStrokeColor(context, 255/255.0f, 0, 0, 1);//设置笔触颜色
    CGContextSetRGBFillColor(context, 0, 255/255.0f, 0, 1);//设置填充色
    CGContextSetLineWidth(context, 2.0);//设置线条宽度
    CGContextSetLineCap(context, kCGLineCapRound);//设置顶点样式,(20,50)和(300,100)是顶点
    CGContextSetLineJoin(context, kCGLineJoinRound);//设置连接点样式,(20,100)是连接点
    /*设置线段样式
     phase:虚线开始的位置
     lengths:虚线长度间隔(例如下面的定义说明第一条线段长度8,然后间隔3重新绘制8点的长度线段,当然这个数组可以定义更多元素)
     count:虚线数组元素个数
     */
    CGFloat lengths[]={18,9,9,4};
    CGContextSetLineDash(context, 0, lengths, 4);
    /*设置阴影
     context:图形上下文
     offset:偏移量
     blur:模糊度
     color:阴影颜色
     */
    CGColorRef color=[UIColor grayColor].CGColor;//;//颜色转化,由于Quartz 2D跨平台,所以其中不能使用UIKit中的对象,但是UIkit提供了转化方法
    CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 0.8, color);
    
    //绘制图像到指定图形上下文
    /*CGPathDrawingMode是填充方式,枚举类型
     kCGPathFill:只有填充(非零缠绕数填充),不绘制边框
     kCGPathEOFill:奇偶规则填充(多条路径交叉时,奇数交叉填充,偶交叉不填充)
     kCGPathStroke:只有边框
     kCGPathFillStroke:既有边框又有填充
     kCGPathEOFillStroke:奇偶填充并绘制边框
     */
    CGContextDrawPath(context, kCGPathFillStroke);
    CGPathRelease(path);
    CGColorRelease(color);
}

运行效果

   

  *简化绘图方式

  CoreGraphics内部对创建对象添加到上下文进行了封装可以一步完成,UIKit内部封装了一些以“UI”开头的方法可以进行图形绘制

//简化绘图,创建一个小三角
-(void)createTriangleSimplifyView{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //绘制路径
    CGContextMoveToPoint(context, 20, 50);
    CGContextAddLineToPoint(context, 20, 100);
    CGContextAddLineToPoint(context, 300, 100);
    //封闭路径:a.创建一条起点和终点的线,不推荐
    //CGPathAddLineToPoint(path, nil, 20, 50);
    //封闭路径:b.直接调用路径封闭方法
    CGContextClosePath(context);
    //设置图形上下文属性
    CGContextClosePath(context);
    [[UIColor redColor] setStroke];//设置红色边框
    [[UIColor greenColor] setFill];//设置绿色填充
    //绘制路径
    CGContextDrawPath(context, kCGPathFillStroke);
}

运行效果

  *绘制矩形

//绘制矩形
-(void)createRect{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGContextAddRect(context, CGRectMake(20, 50, 280.0, 50.0));
    //设置属性
    [[UIColor blueColor] set];
    CGContextDrawPath(context, kCGPathFillStroke);
    
    [[UIColor yellowColor] set];
    UIRectFill(CGRectMake(20, 150, 280.0, 50.0));//绘制矩形(只有填充)
    
    [[UIColor redColor] setStroke];
    UIRectFrame(CGRectMake(20, 250, 280.0, 50));//绘制矩形(只有边框)
}

运行效果

  *绘制椭圆

//绘制椭圆
-(void)createEllipse{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //添加对象,绘制椭圆(圆形)的过程也是先创建一个矩形
    CGContextAddEllipseInRect(context, CGRectMake(0, 0, 200, 200));
    //设置属性
    [[UIColor purpleColor] set];
    //绘制
    CGContextDrawPath(context, kCGPathFillStroke);
}

运行效果

  *绘制弧形

//绘制弧形
-(void)createArcView{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    
    /*添加弧形对象
     x:中心点x坐标
     y:中心点y坐标
     radius:半径
     startAngle:起始弧度
     endAngle:终止弧度
     closewise:是否逆时针绘制,0则顺时针绘制
     */
    CGContextAddArc(context, 80, 80, 60, 0, M_PI_2, 1);
    //设置属性
    [[UIColor yellowColor] set];
    //绘制
    CGContextDrawPath(context, kCGPathFillStroke);
}

 

运行效果

  *绘制贝塞尔曲线

//绘制二次/三次贝塞尔曲线
-(void)createCurveView{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //绘制曲线
    CGContextMoveToPoint(context, 20, 100);//移动到起始位置
    /*绘制二次贝塞尔曲线
     c:图形上下文
     cpx:控制点x坐标
     cpy:控制点y坐标
     x:结束点x坐标
     y:结束点y坐标
     */
    CGContextAddQuadCurveToPoint(context, 160, 0, 300, 100);
    
    CGContextMoveToPoint(context, 20, 500);
    /*绘制三次贝塞尔曲线
     c:图形上下文
     cp1x:第一个控制点x坐标
     cp1y:第一个控制点y坐标
     cp2x:第二个控制点x坐标
     cp2y:第二个控制点y坐标
     x:结束点x坐标
     y:结束点y坐标
     */
    CGContextAddCurveToPoint(context, 80, 300, 240, 500, 300, 300);
    
    //设置图形上下文属性
    [[UIColor yellowColor] setFill];
    [[UIColor redColor] setStroke];
    
    //绘制路径
    CGContextDrawPath(context, kCGPathFillStroke);
}

运行效果

  *文本绘制

//文本绘制
-(void)createTextView{
    //绘制到指定内容区域
    NSString *str=@"Star Walk is the most beautiful stargazing app you’ve ever seen on a mobile device. It will become your go-to interactive astro guide to the night sky, following your every movement in real-time and allowing you to explore over 200, 000 celestial bodies with extensive information about stars and constellations that you find.";
    UIFont *font=[UIFont systemFontOfSize:18];//设置字体
    UIColor *color=[UIColor redColor];//字体颜色
    NSMutableParagraphStyle *style=[[NSMutableParagraphStyle alloc] init];//段落样式
    NSTextAlignment align=NSTextAlignmentLeft;//对齐方式
    style.alignment=align;
    [str drawInRect:CGRectMake(20, 50, 280, 300) withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:color,NSParagraphStyleAttributeName:style}];
}

运行效果

  *图像绘制

//图像绘制
-(void)createImgae{
    UIImage *img=[UIImage imageNamed:@"🤤.png"];
    //从某一点开始绘制
//    [img drawAtPoint:CGPointMake(10, 50)];
    //绘制到指定的矩形中,注意如果大小不合适会会进行拉伸
    [img drawInRect:CGRectMake(10, 50, 256, 160)];
    //平铺绘制
//    [img drawAsPatternInRect:CGRectMake(0, 0, 320, 568)];
}

运行效果

  *绘制渐变填充

线性渐变线:渐变色以直线方式从开始位置逐渐向结束位置渐变

//线性渐变线:渐变色以直线方式从开始位置逐渐向结束位置渐变
-(void)createLinearGradient{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //使用rgb颜色空间
    CGColorSpaceRef colorSpac=CGColorSpaceCreateDeviceRGB();
    /*指定渐变色
     space:颜色空间
     components:颜色数组,注意由于指定了RGB颜色空间,那么四个数组元素表示一个颜色(red、green、blue、alpha),
     如果有三个颜色则这个数组有4*3个元素
     locations:颜色所在位置(范围0~1),这个数组的个数不小于components中存放颜色的个数
     count:渐变个数,等于locations的个数
     */
    CGFloat compoents[12]={
        248.0/255.0,86.0/255.0,86.0/255.0,1,
        249.0/255.0,127.0/255.0,127.0/255.0,1,
        1.0,1.0,1.0,1.0
    };
    CGFloat locations[3]={0,0.3,1.0};
    CGGradientRef gradient=CGGradientCreateWithColorComponents(colorSpac, compoents, locations, 3);
    
    /*绘制线性渐变
     context:图形上下文
     gradient:渐变色
     startPoint:起始位置
     endPoint:终止位置
     options:绘制方式,kCGGradientDrawsBeforeStartLocation 开始位置之前就进行绘制,到结束位置之后不再绘制,
     kCGGradientDrawsAfterEndLocation开始位置之前不进行绘制,到结束点之后继续填充
     */
    CGContextDrawLinearGradient(context, gradient, CGPointMake(self.frame.size.width/2, 0), CGPointMake(self.frame.size.width/2, self.frame.size.height), kCGGradientDrawsAfterEndLocation);
    //释放颜色空间
    CGColorSpaceRelease(colorSpac);
}

运行效果

径向渐变:以中心点为圆心从起始渐变色向四周辐射,直到终止渐变色

//径向渐变:以中心点为圆心从起始渐变色向四周辐射,直到终止渐变色
-(void)createRadialGradient{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //使用rgb颜色空间
    CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
    
    /*指定渐变色
     space:颜色空间
     components:颜色数组,注意由于指定了RGB颜色空间,那么四个数组元素表示一个颜色(red、green、blue、alpha),
     如果有三个颜色则这个数组有4*3个元素
     locations:颜色所在位置(范围0~1),这个数组的个数不小于components中存放颜色的个数
     count:渐变个数,等于locations的个数
     */
    CGFloat compoents[12]={
        248.0/255.0,86.0/255.0,86.0/255.0,1,
        249.0/255.0,127.0/255.0,127.0/255.0,1,
        1.0,1.0,1.0,1.0
    };
    CGFloat locations[3]={0,0.3,1.0};
    CGGradientRef gradient=CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3);
    /*绘制径向渐变
     context:图形上下文
     gradient:渐变色
     startCenter:起始点位置
     startRadius:起始半径(通常为0,否则在此半径范围内容无任何填充)
     endCenter:终点位置(通常和起始点相同,否则会有偏移)
     endRadius:终点半径(也就是渐变的扩散长度)
     options:绘制方式,kCGGradientDrawsBeforeStartLocation 开始位置之前就进行绘制,但是到结束位置之后不再绘制,
     kCGGradientDrawsAfterEndLocation开始位置之前不进行绘制,但到结束点之后继续填充
     */
    CGContextDrawRadialGradient(context, gradient, CGPointMake(self.frame.size.width/2, self.frame.size.height/2), 0, CGPointMake(self.frame.size.width/2, self.frame.size.height/2), 150, kCGGradientDrawsBeforeStartLocation);
    //释放颜色空间
    CGColorSpaceRelease(colorSpace);
}

运行效果

  *扩展--渐变填充

//区域裁剪线性渐变填充
-(void)createRectWithLinearGradientFill{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //使用rgb颜色空间
    CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
    //裁切处一块矩形用于显示,注意必须先裁切再调用渐变
    //CGContextClipToRect(context, CGRectMake(20, 50, 280, 300));
    //裁切还可以使用UIKit中对应的方法
    UIRectClip(CGRectMake(20, 50, 280, 300));
    
    CGFloat compoents[12]={
        248.0/255.0,86.0/255.0,86.0/255.0,1,
        249.0/255.0,127.0/255.0,127.0/255.0,1,
        1.0,1.0,1.0,1.0
    };
    CGFloat locations[3]={0,0.3,1.0};
    CGGradientRef gradient=CGGradientCreateWithColorComponents(colorSpace, compoents, locations, 3);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(150, 50), CGPointMake(150, 300), kCGGradientDrawsAfterEndLocation);
    //释放颜色空间
    CGColorSpaceRelease(colorSpace);
}

运行效果

  *叠加模式

  使用Quartz2D绘图时后面绘制的图像会覆盖前面的,默认情况下如果前面的被覆盖后将看不到后面的内容,但Quartz2D中提供了填充模式供开发者配置调整。

//叠加模式,(视图有背景色,和没背景色是不一样的)
-(void)createRectByUIKit{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    
    CGRect rect= CGRectMake(0, 130.0, 320.0, 50.0);
    CGRect rect1= CGRectMake(0, 390.0, 320.0, 50.0);
    
    
    CGRect rect2=CGRectMake(20, 50.0, 10.0, 250.0);
    CGRect rect3=CGRectMake(40.0, 50.0, 10.0, 250.0);
    CGRect rect4=CGRectMake(60.0, 50.0, 10.0, 250.0);
    CGRect rect5=CGRectMake(80.0, 50.0, 10.0, 250.0);
    CGRect rect6=CGRectMake(100.0, 50.0, 10.0, 250.0);
    CGRect rect7=CGRectMake(120.0, 50.0, 10.0, 250.0);
    CGRect rect8=CGRectMake(140.0, 50.0, 10.0, 250.0);
    CGRect rect9=CGRectMake(160.0, 50.0, 10.0, 250.0);
    CGRect rect10=CGRectMake(180.0, 50.0, 10.0, 250.0);
    CGRect rect11=CGRectMake(200.0, 50.0, 10.0, 250.0);
    CGRect rect12=CGRectMake(220.0, 50.0, 10.0, 250.0);
    CGRect rect13=CGRectMake(240.0, 50.0, 10.0, 250.0);
    CGRect rect14=CGRectMake(260.0, 50.0, 10.0, 250.0);
    CGRect rect15=CGRectMake(280.0, 50.0, 10.0, 250.0);
    
    CGRect rect16=CGRectMake(30.0, 310.0, 10.0, 250.0);
    CGRect rect17=CGRectMake(50.0, 310.0, 10.0, 250.0);
    CGRect rect18=CGRectMake(70.0, 310.0, 10.0, 250.0);
    CGRect rect19=CGRectMake(90.0, 310.0, 10.0, 250.0);
    CGRect rect20=CGRectMake(110.0, 310.0, 10.0, 250.0);
    CGRect rect21=CGRectMake(130.0, 310.0, 10.0, 250.0);
    CGRect rect22=CGRectMake(150.0, 310.0, 10.0, 250.0);
    CGRect rect23=CGRectMake(170.0, 310.0, 10.0, 250.0);
    CGRect rect24=CGRectMake(190.0, 310.0, 10.0, 250.0);
    CGRect rect25=CGRectMake(210.0, 310.0, 10.0, 250.0);
    CGRect rect26=CGRectMake(230.0, 310.0, 10.0, 250.0);
    CGRect rect27=CGRectMake(250.0, 310.0, 10.0, 250.0);
    CGRect rect28=CGRectMake(270.0, 310.0, 10.0, 250.0);
    CGRect rect29=CGRectMake(290.0, 310.0, 10.0, 250.0);
    
    
    [[UIColor yellowColor]set];
    UIRectFill(rect);
    
    [[UIColor greenColor]setFill];
    UIRectFill(rect1);
    
    [[UIColor redColor]setFill];
    UIRectFillUsingBlendMode(rect2, kCGBlendModeClear);
    UIRectFillUsingBlendMode(rect3, kCGBlendModeColor);
    UIRectFillUsingBlendMode(rect4, kCGBlendModeColorBurn);
    UIRectFillUsingBlendMode(rect5, kCGBlendModeColorDodge);
    UIRectFillUsingBlendMode(rect6, kCGBlendModeCopy);
    UIRectFillUsingBlendMode(rect7, kCGBlendModeDarken);
    UIRectFillUsingBlendMode(rect8, kCGBlendModeDestinationAtop);
    UIRectFillUsingBlendMode(rect9, kCGBlendModeDestinationIn);
    UIRectFillUsingBlendMode(rect10, kCGBlendModeDestinationOut);
    UIRectFillUsingBlendMode(rect11, kCGBlendModeDestinationOver);
    UIRectFillUsingBlendMode(rect12, kCGBlendModeDifference);
    UIRectFillUsingBlendMode(rect13, kCGBlendModeExclusion);
    UIRectFillUsingBlendMode(rect14, kCGBlendModeHardLight);
    UIRectFillUsingBlendMode(rect15, kCGBlendModeHue);
    UIRectFillUsingBlendMode(rect16, kCGBlendModeLighten);
    
    UIRectFillUsingBlendMode(rect17, kCGBlendModeLuminosity);
    UIRectFillUsingBlendMode(rect18, kCGBlendModeMultiply);
    UIRectFillUsingBlendMode(rect19, kCGBlendModeNormal);
    UIRectFillUsingBlendMode(rect20, kCGBlendModeOverlay);
    UIRectFillUsingBlendMode(rect21, kCGBlendModePlusDarker);
    UIRectFillUsingBlendMode(rect22, kCGBlendModePlusLighter);
    UIRectFillUsingBlendMode(rect23, kCGBlendModeSaturation);
    UIRectFillUsingBlendMode(rect24, kCGBlendModeScreen);
    UIRectFillUsingBlendMode(rect25, kCGBlendModeSoftLight);
    UIRectFillUsingBlendMode(rect26, kCGBlendModeSourceAtop);
    UIRectFillUsingBlendMode(rect27, kCGBlendModeSourceIn);
    UIRectFillUsingBlendMode(rect28, kCGBlendModeSourceOut);
    UIRectFillUsingBlendMode(rect29, kCGBlendModeXOR);
}

运行效果

  *填充模式

按一定的自定义样式进行填充,有点类似于贴瓷砖的方式

有颜色填充模式

//填充模式,有颜色填充模式
void drawColoredTile(void *info,CGContextRef context){
    CGContextSetRGBFillColor(context, 254.0/255.0, 52.0/255.0, 90.0/255.0, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 20, 20));
    CGContextSetRGBFillColor(context, 187.0/255.0, 299.0/255.0, 299.0/255.0, 1);
    CGContextFillRect(context, CGRectMake(20, 20, 20, 20));
}
-(void)createBackgroundWithColoredPattern{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //模式填充颜色空间,注意对于有颜色填充模式,这里传NULL
    CGColorSpaceRef colorSpace=CGColorSpaceCreatePattern(NULL);
    //将填充颜色空间设置为模式填充的颜色空间
    CGContextSetFillColorSpace(context, colorSpace);
    
    //填充模式回调函数结构体
    CGPatternCallbacks callback={0,&drawColoredTile,NULL};
    /*填充模式
     info://传递给callback的参数
     bounds:瓷砖大小
     matrix:形变
     xStep:瓷砖横向间距
     yStep:瓷砖纵向间距
     tiling:贴砖的方法
     isClored:绘制的瓷砖是否已经指定了颜色(对于有颜色瓷砖此处指定位true)
     callbacks:回调函数
     */
    CGPatternRef pattern=CGPatternCreate(NULL, CGRectMake(0, 0, 2*20, 2*20), CGAffineTransformIdentity, 2*20, 2*20, kCGPatternTilingNoDistortion, true, &callback);
    CGFloat alpha=1;
    //注意最后一个参数对于有颜色瓷砖指定为透明度的参数地址,对于无颜色瓷砖则指定当前颜色空间对应的颜色数组
    CGContextSetFillPattern(context, pattern, &alpha);
    UIRectFill(self.frame);
    CGColorSpaceRelease(colorSpace);
    CGPatternRelease(pattern);
}

运行效果

无颜色填充模式

//填充模式,无颜色填充
//填充瓷砖的回调函数(必须满足CGPatternCallbacks签名)
void drawTile(void *info,CGContextRef context){
    CGContextFillRect(context, CGRectMake(0, 0, 20, 20));
    CGContextFillRect(context, CGRectMake(20, 20, 20, 20));
}
-(void)createBackgroundWithPattern{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //设备无关的颜色空间
    CGColorSpaceRef rgbSpace=CGColorSpaceCreateDeviceRGB();
    //模式填充颜色空间
    CGColorSpaceRef colorSpace=CGColorSpaceCreatePattern(rgbSpace);
    //将填充颜色空间设置为模式填充颜色空间
    CGContextSetFillColorSpace(context, colorSpace);
    //填充模式回调函数结构体
    CGPatternCallbacks callback={0,&drawTile,NULL};
    /*填充模式
     info://传递给callback的参数
     bounds:瓷砖大小
     matrix:形变
     xStep:瓷砖横向间距
     yStep:瓷砖纵向间距
     tiling:贴砖的方法(瓷砖摆放的方式)
     isClored:绘制的瓷砖是否已经指定了颜色(对于无颜色瓷砖此处指定位false)
     callbacks:回调函数
     */
    CGPatternRef pattern=CGPatternCreate(NULL, CGRectMake(0, 0, 2*20, 2*20), CGAffineTransformIdentity, 2*20, 2*20, kCGPatternTilingNoDistortion, false, &callback);
    
    CGFloat componets[]={254.0/255.0,52.0/255.0,90.0/255.0,1.0};
    //注意最后一个参数对于无颜色填充模式指定为当前颜色空间颜色数据
    CGContextSetFillPattern(context, pattern, componets);
    UIRectFill(self.frame);
    CGColorSpaceRelease(rgbSpace);
    CGColorSpaceRelease(colorSpace);
    CGPatternRelease(pattern);
}

运行效果

  *上下文变换

//图形上下文形变
-(void)createTranslate{
    //获得图形上下文
    CGContextRef context=UIGraphicsGetCurrentContext();
    //保持初始状态
    CGContextSaveGState(context);
    //形变第一步:图形上下文向右平移100
    CGContextTranslateCTM(context, 100, 200);
    //形变第二步:缩放0.8
    CGContextScaleCTM(context, 0.7, -0.7);
    //形变第三步旋转
    CGContextRotateCTM(context, M_PI_4/4);
    
    UIImage *img=[UIImage imageNamed:@"🤤.png"];
    //使用CoreGraphics绘制图像
    //在Core Graphics中坐标系的y轴正方向是向上的,坐标原点在屏幕左下角,y轴方向刚好和UIKit中y轴方向相反。其实图形上下文只要沿着x轴旋转180度,然后向上平移适当的高度即可
    CGContextDrawImage(context, CGRectMake(10, 50, 256, 160), img.CGImage);

    
    //恢复到初始状态
    CGContextRestoreGState(context);
}

运行效果

  *视图刷新

  在UIView的drawRect:中绘制的图形会在控件显示的时候调用(而且显示时会重绘所有图形),有时会要求绘制内容的显示是实时的,此时就要调用绘图方法重新绘制。刷新绘图内容需要调用setNeedsDisplay方法,不允许开发者直接调用drawRect:方法

  *其他图形上下文

  绘制到位图

//利用位图上下文绘制
-(void)createBitmapContext{
    //获得一个位图图形上下文
    CGSize size=CGSizeMake(250, 160);//画布大小
    UIGraphicsBeginImageContext(size);
    
    UIImage *img=[UIImage imageNamed:@"🤤.png"];
    [img drawInRect:CGRectMake(0, 0, 250, 160)];//注意绘图的位置是相对于布画顶点而言,不是屏幕
    //添加水印
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(context, 150, 150);
    CGContextAddLineToPoint(context, 220, 150);
    
    [[UIColor cyanColor] setStroke];
    CGContextSetLineWidth(context, 2);
    CGContextDrawPath(context, kCGPathStroke);
    NSString *str=@"Burning life";
    [str drawInRect:CGRectMake(150, 130, 100, 30) withAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Marker Felt" size:15],NSForegroundColorAttributeName:[UIColor cyanColor]}];
    //返回绘制新的图形
    UIImage *newImage=UIGraphicsGetImageFromCurrentImageContext();
    //关闭对应的上下文
    UIGraphicsEndImageContext();
    
    //绘制图片到视图
    [newImage drawInRect:CGRectMake((self.frame.size.width-250)/2, (self.frame.size.height-160)/2, 250, 160)];
}

运行效果

  绘制到PDF

绘制到PDF要启用PDF图形上下文,绘制到内容到PDF时需要创建分页,每页内容的开始都要调用一次UIGraphicsBeginPDFPage()方法

/绘制到pdf,绘制出的pdf可以真机运行后使用iTools到app的Documents文件夹查看
-(void)createContentToPdfContext{
    NSString *filePath=[NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"/Documents/%@",@"myPDF.pdf"]];
    NSLog(@"%@",filePath);
    //启用pdf图形上下文
    /**
     path:保存路径
     bounds:pdf文档大小,如果设置为CGRectZero则使用默认值:612*792
     pageInfo:页面设置,为nil则不设置任何信息
     */
    UIGraphicsBeginPDFContextToFile(filePath, CGRectZero, [NSDictionary dictionaryWithObjectsAndKeys:@"Vie",kCGPDFContextAuthor, nil]);
    
    //由于pdf文档是分页的,所以首先要创建一页画布供我们绘制
    UIGraphicsBeginPDFPage();
    
    NSString *title=@"Welcome to Apple Support";
    NSMutableParagraphStyle *style=[[NSMutableParagraphStyle alloc]init];
    NSTextAlignment align=NSTextAlignmentCenter;
    style.alignment=align;
    [title drawInRect:CGRectMake(26, 20, 300, 50) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:18],NSParagraphStyleAttributeName:style}];
    NSString *content=@"Learn about Apple products, view online manuals, get the latest downloads, and more. Connect with other Apple users, or get service, support, and professional advice from Apple.";
    NSMutableParagraphStyle *style2=[[NSMutableParagraphStyle alloc]init];
    style2.alignment=NSTextAlignmentLeft;
    //    style2.firstLineHeadIndent=20;
    [content drawInRect:CGRectMake(26, 56, 300, 255) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor grayColor],NSParagraphStyleAttributeName:style2}];
    
    UIImage *image=[UIImage imageNamed:@"🤤.png"];
    [image drawInRect:CGRectMake(316, 20, 290, 305)];
    
    UIImage *image2=[UIImage imageNamed:@"🤤.png"];
    [image2 drawInRect:CGRectMake(6, 320, 600, 281)];
    
    //创建新的一页继续绘制其他内容
    UIGraphicsBeginPDFPage();
    UIImage *image3=[UIImage imageNamed:@"🤤.png"];
    [image3 drawInRect:CGRectMake(6, 20, 600, 629)];
    
    //结束pdf上下文
    UIGraphicsEndPDFContext();
}

   *CoreImage

iOS5.0开始提供了CoreImage框架来进行滤镜特效制作

CIContext:图像上下文,用于管理整个图片处理过程,不同的图形上下文将利用不同的图像处理硬件进行图像处理(在iOS中可以通过不同的方式创建图像上下文,例如可以创建基于CPU的图像上下方、创建基于GPU的图像上下方以及创建OpenGL优化过的图像上下文)。

CIFilter:图像处理滤镜,每种滤镜有不同的参数设置。

CIImage:Core Image框架中的图像类型,主要用于输入和输出图像。

//图像滤镜处理
-(void)showAllFilters{
    #pragma mark 查看所有内置滤镜
    NSArray *filterNames=[CIFilter filterNamesInCategory:kCICategoryBuiltIn];
    for (NSString *filterName in filterNames) {
        CIFilter *filter=[CIFilter filterWithName:filterName];
        NSLog(@"\rfilter:%@\rattributes:%@",filterName,[filter attributes]);
    }
    
    CIContext *context;//Core Image上下文
    CIImage *image;//我们要编辑的图像
    CIImage *outputImage;//处理后的图像
    CIFilter *colorControlsFilter;//色彩滤镜
    context=[CIContext contextWithOptions:nil];//使用GPU渲染,推荐,但注意GPU的CIContext无法跨应用访问,例如直接在UIImagePickerController的完成方法中调用上下文处理就会自动降级为CPU渲染,所以推荐现在完成方法中保存图像,然后在主程序中调用
    //初始化CIImage源图像
    image=[CIImage imageWithCGImage:[UIImage imageNamed:@"🤤.png"].CGImage];
    //取得滤镜
    colorControlsFilter=[CIFilter filterWithName:@"CIColorControls"];
    [colorControlsFilter setValue:image forKey:@"inputImage"];//设置滤镜的输入图片
    
    //调整饱和度
    [colorControlsFilter setValue:[NSNumber numberWithFloat:0.8] forKey:@"inputSaturation"];//设置滤镜参数
    //调整亮度
    [colorControlsFilter setValue:[NSNumber numberWithFloat:0.1] forKey:@"inputBrightness"];
    //调整对比度
    [colorControlsFilter setValue:[NSNumber numberWithFloat:0.8] forKey:@"inputContrast"];
    //转换图片
    outputImage= [colorControlsFilter outputImage];//取得输出图像
    CGImageRef temp=[context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *outImg=[UIImage imageWithCGImage:temp];
    [outImg drawInRect:CGRectMake(0, 0, 250, 160)];
    CGImageRelease(temp);//释放CGImage对象
}

运行效果