美文网首页程序员iOS DeveloperiOS
CGContextSaveGState(重点) 与 UIGrap

CGContextSaveGState(重点) 与 UIGrap

作者: 兰州一碗面 | 来源:发表于2017-01-03 21:03 被阅读121次

有一个需求,每次push一个页面的时候,push过去的页面的背景图片需要时上一个页面的样子。。。不知道有没有用这短小精干的语言描述清楚。

<br />

那么这个需求我是这么考虑的,把window转换成image,然后传入下一个页面。

<br />

所以接触了一下Quart2D。

<br />

今天就来说说CGContextSaveGState(主要),UIGraphicsPushContext。

- (void)drawRect:(CGRect)rect{ // do drawing here}

在iOS绘图的时候大家都会用到这个这个方法。
在调用这个方法之前,绘画系统创建了一个上下文(CGContext),也可以说是画布。上下文中包含了很多信息,比如画笔颜色,字体颜色,填充颜色,字体,形状等等。
由于只有一个CGContext,也就是说只有一个画笔,如果你变化了画笔的颜色等状态,就会影响函数调用的结果,那么我们就会用到CGContextSaveGState与CGContextRestoreGState将上下文入栈出栈。

通常CGContextSaveGState和CGContextRestoreGState都是成对出现的。

<br />

- (void)drawRect:(CGRect)rect{ 
    //1.获得当前上下文
    CGContextRef context=UIGraphicsGetCurrentContext(); 
    //2.设置画笔颜色为红色,并入栈上下文,之后把画笔改为黑色,然后出栈上下文,你会发现画笔又变为了最初的红色。
    [[UIColor redColor] setStroke];       
    CGContextSaveGState(UIGraphicsGetCurrentContext());   
    [[UIColor blackColor] setStroke]; 
    CGContextRestoreGState(UIGraphicsGetCurrentContext());   
    UIRectFill(CGRectMake(10, 10, 100, 100)); // 红
}

UIGraphicsPushContext

如果这段代码中的CGContextSaveGState和CGContextRestoreGState换成UIGraphicsPushContext和UIGraphicsPopContext就不对了。
因为UIGraphicsPushContext并没有保存该上下文当前状态的功能,而是完全的切换上下文。

那么什么时候会用到UIGraphicsPushContext呢?

假设你正在当前视图上下文中绘制什么东西,这时想要在位图上下文中绘制完全不同的东西。如果要使用UIKit来进行任意绘图,你会希望保存当前的UIKit上下文,包括所有已经绘制的内容,接着切换到一个全新的绘图上下文中。这就是UIGraphicsPushContext的功能。创建完位图后,再将你的旧上下文出栈。而这就是UIGraphicsPopContext的功能。这种情况只会在要使用UIKit在新的位图上下文中绘图时才会发生。只要你使用的是Core Graphics函数,就不需要去执行上下文入栈和出栈,因为Core Graphics函数将上下文视作参数。(摘录自http://blog.csdn.net/lihangqw/article/details/9969961

接下来就说说UIImage绘制的一些操作

一般步骤为:
UIGraphicsBeginImageContext(CGSize size)
或者
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
准备绘图环境
CGContextRef __nullable UIGraphicsGetCurrentContext(void)
获取绘图的CGContextRef
开始绘图
UIImage* UIGraphicsGetImageFromCurrentImageContext(void);
获取当前绘制的图形
void UIGraphicsEndImageContext(void);
关闭绘图环境

接下来就从几个简单的🌰 中体会一下吧~
//图片按比例压缩
-(UIImage *)image:(UIImage *)img toScale:(float)scale {
      UIGraphicsBeginImageContext(CGSizeMake(img.size.width, img.size.height)); //准备绘画环境
      [img drawInRect:CGRectMake(0, 0, img.size.width * scale, img.size.height * scale)];//绘画
      UIImage *endImg = UIGraphicsGetImageFromCurrentImageContext();//获取当前绘制的图形
      UIGraphicsEndImageContext();//结束绘画
      return endImg;
}
//将UIView转为UIImage
- (UIImage *)captureView:(UIView *)theView {
    
    CGRect rect = theView.frame;
    
    UIGraphicsBeginImageContext(rect.size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextTranslateCTM(context, 0, -70); //截取位置下移70
    
    [theView.layer renderInContext:context];
    
    UIImage *endImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return endImage;
    
}
//截取图片

- (UIImage *)getImageWithImage:(UIImage *)img {
    
    CGRect myRect = CGRectMake(10, 10,300, 300);
    
    CGImageRef bigRef = img.CGImage;
    
    CGImageRef subImageRef = CGImageCreateWithImageInRect(bigRef, myRect);
    
    CGSize size = CGSizeMake(300, 300);
    
    UIGraphicsBeginImageContext(size);
    
    CGContextDrawImage(UIGraphicsGetCurrentContext(), myRect, subImageRef);
    
    UIImage *smallImage = [UIImage imageWithCGImage:subImageRef];
    
    UIGraphicsEndImageContext();
    
    return smallImage;
    
}
//截取当前屏幕
+ (UIImage *)screenshot
{
    CGSize imageSize = [[UIScreen mainScreen] bounds].size;
 
    UIGraphicsBeginImageContext(imageSize);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) {
            CGContextSaveGState(context);

            CGContextTranslateCTM(context, [window center].x, [window center].y);

            CGContextConcatCTM(context, [window transform]);
            
            CGContextTranslateCTM(context,
                                  -[window bounds].size.width * [[window layer] anchorPoint].x,
                                  -[window bounds].size.height * [[window layer] anchorPoint].y);
            
            [[window layer] renderInContext:context];
            
            CGContextRestoreGState(context);
        }
    }
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return image;
}
//将两张图片合成一张

- (UIImage *)addImageWithImage1:(UIImage *)image1 Image2:(UIImage *)image2 {
    
    UIGraphicsBeginImageContext(image1.size);
    
    [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
    
    [image2 drawInRect:CGRectMake(0, 0, image2.size.width-200, image2.size.height-200)];
    
    UIImage *endImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return endImage;
    
}
//截取scrollview

-(UIImage *)captureScrollView:(UIScrollView *)scrollView{

    UIImage* image = nil;

    UIGraphicsBeginImageContext(scrollView.contentSize);

    scrollView.contentOffset = CGPointZero;

    scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);

    [scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];

    image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;

}

相关文章

网友评论

    本文标题:CGContextSaveGState(重点) 与 UIGrap

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