CGContextSaveGState(重点) 与 UIGraphicsPushContext

有一个需求,每次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;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容