美文网首页iOS Crazies
Core Graphics之CGContext详解

Core Graphics之CGContext详解

作者: hehtao | 来源:发表于2016-11-24 15:01 被阅读170次

    CGContext又叫图形上下文,相当于一块画布,以堆栈形式存放,只有在当前 context上绘图才有效。iOS有分多种图形上下文,其中UIView自带提供的在drawRect:方法中通过 UIGraphicsGetCurrentContext获取,还有专门为图片处理的context,UIGraphicsBeginImageContext函数生成,还有pdf的context等等。

    1.一共有3种使用context的场景,其中每种场景都有2种方法绘图

    场景1:

    //通过UIView的子类的drawRect:在上下文中绘制,该方法系统已准备好一个cgcontext,并放置在上下文栈顶,rect形参就是context的尺寸大小
    //当一个UIView的backgroundColor为nil和opaque为YES时,产生的context的背景就为黑色的

    - (void)drawRect:(CGRect)rect
    {
        //1.使用UIKit在context上绘制,UIKit的所有操作只会在当前栈顶的context,所以需要注意当前栈顶的context是否你需要操作的上下文
        //UIImage,NSString,UIBezierPath,UIColor等可以直接在当前context上操作
        UIImage* image = [UIImage imageNamed:@"test.png"];
        NSLog(@"size:%@",NSStringFromCGSize(image.size));
        //UIImage直接在context上操作,指定在context的哪个坐标上绘制,大小是原图的尺寸,如果大小超出了context的范围就会被截取掉
       // [image drawAtPoint:CGPointMake(100, 100)];
        //指定在context的哪个坐标上绘制,并指定绘制的图片尺寸大小,这样图片的尺寸就会被压缩,不会超出context范围
        [image drawInRect:CGRectMake(0, 0, rect.size.width/2, rect.size.height/2)];
       
    

    //2.使用Core Graphics的函数在context上绘制,Core Graphics的函数需要context作为参数,只绘制在指定使用的context上

        //功过UIGraphicsGetCurrentContext函数获取当前上下文栈顶的context,UIView系统已为其准备好context并存放在栈顶了
        CGContextRef context = UIGraphicsGetCurrentContext();
    //    //画一个椭圆
        CGContextAddEllipseInRect(context, CGRectMake(0,0,100,100));
        //填充颜色为蓝色
        CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
    //    //在context上绘制
        CGContextFillPath(context);
    

    场景2:

    //实现该方法,用于CALayer回调,CALayer通过它的代理类来进行绘图操作,切记千万不能把UIView作为CALayer的代理类,因为UIView自身有隐式的图层,若再把显式的图层赋给它会发生不知名错误的

    - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
    {
        //1.使用UIKit进行绘制,因为UIKit只会对当前上下文栈顶的context操作,所以要把形参中的context设置为当前上下文
        UIGraphicsPushContext(ctx);
        UIImage* image = [UIImage imageNamed:@"test.png"];
        //指定位置和大小绘制图片
        [image drawInRect:CGRectMake(0, 0,100 , 100)];
        UIGraphicsPopContext();
        
        //    UIGraphicsPushContext(ctx);
        //2.使用Core Graphics进行绘制,需要显式使用context
        //    //画一个椭圆
        //    CGContextAddEllipseInRect(ctx, CGRectMake(0,0,100,100));
        //    //填充颜色为蓝色
        //    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
        //    //在context上绘制
        //    CGContextFillPath(ctx);
        //    UIGraphicsPopContext();
    }
    
    
        LayerDelegate* delegate = [[LayerDelegate alloc]init];
        CALayer* layer = [CALayer layer];
        layer.anchorPoint = CGPointMake(0, 0);
        layer.position = CGPointMake(100, 100);
        layer.bounds = CGRectMake(0, 0, 200, 200);
        layer.delegate = delegate;
        //需要显式调用setNeedsDisplay来刷新才会绘制layer
        [layer setNeedsDisplay];
        [self.view.layer addSublayer:layer];
    
    

    下图为场景1和场景2的显示效果:

    场景3:

    //通过自己创建一个context来绘制,通常用于对图片的处理
    /*
    解释一下UIGraphicsBeginImageContextWithOptions函数参数的含义:第一个参数表示所要创建的图片的尺寸;第二个参 数用来指定所生成图片的背景是否为不透明,如上我们使用YES而不是NO,则我们得到的图片背景将会是黑色,显然这不是我想要的;第三个参数指定生成图片 的缩放因子,这个缩放因子与UIImage的scale属性所指的含义是一致的。传入0则表示让图片的缩放因子根据屏幕的分辨率而变化,所以我们得到的图 片不管是在单分辨率还是视网膜屏上看起来都会很好。

         */
        //该函数会自动创建一个context,并把它push到上下文栈顶,坐标系也经处理和UIKit的坐标系相同
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextAddEllipseInRect(context, CGRectMake(0,0,100,100));
        //填充颜色为蓝色
        CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
        //在context上绘制
        CGContextFillPath(context);
        //把当前context的内容输出成一个UIImage图片
        UIImage* i = UIGraphicsGetImageFromCurrentImageContext();
        //上下文栈pop出创建的context
        UIGraphicsEndImageContext();
        [i drawInRect:CGRectMake(0, 0, 100, 100)];
    
    

    下图为绘制的显示效果:

    2.把整个屏幕转化为图片

        UIImageView* imageV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        UIGraphicsBeginImageContextWithOptions(imageV.frame.size, NO, 0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        //把当前的整个画面导入到context中,然后通过context输出UIImage,这样就可以把整个屏幕转化为图片
        [self.view.layer renderInContext:context];
        UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
        imageV.image = image;
        UIGraphicsEndImageContext();
    
    

    3.剪裁图片

       //对一张图片进行剪裁
        CGImageRef imageref = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(100, 100, 200, 50));
        UIImageView* cropImage = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 200, 50)];
        cropImage.image = [UIImage imageWithCGImage:imageref];
    
       CGImageRelease(imageref);
    
        [self.view addSubview:cropImage];
    

    下图下放的是剪裁后的图片效果:

    相关文章

      网友评论

        本文标题:Core Graphics之CGContext详解

        本文链接:https://www.haomeiwen.com/subject/cnbbpttx.html