CGContextSaveGState和CGContextRestoreGState UIGraphicsPushContext和UIGraphicsPopCo

转载 2013年12月04日 22:29:05

在调用drawRect:方法之前,绘图系统创建了一个图形上下文(CGContext)。上下文包括大量信息,比如画笔颜色、文本颜色、当前字体、变形等。有时你可能想要修改上下文并使其恢复原样。举个例子,你现在有一个使用特定颜色绘制特定形状的函数。由于只能有一只画笔,因此在更改颜色后,就会影响调用函数的结果。为了避免这个副作用,你可以使用CGContextSaveGStateCGContextRestoreGState将上下文入栈和出栈。

请不要与看起来相似的UIGraphicsPushContextUIGraphicsPopContext混淆。它们做的并不是同一件事。CGContextSaveGState记录上下文的当前状态。UIGraphicsPushContext更改当前上下文。以下是CGContextSaveGState的示例。

1
2
3
4
5
    [[UIColor redColor] setStroke];
    CGContextSaveGState(UIGraphicsGetCurrentContext());
    [[UIColor blackColor] setStroke];
    CGContextRestoreGState(UIGraphicsGetCurrentContext());
    UIRectFill(CGRectMake(10, 10, 100, 100)); //

这段代码设置了画笔的颜色为红色并保存了上下文。之后它将把画笔颜色改成黑色并恢复上下文。这样当你绘图的时候,画笔又会变成红色了。

以下代码展示了一个常见的错误。

1
2
3
4
5
6
    [[UIColor redColor] setStroke];
    //下一行不对
    UIGraphicsPushContext(UIGraphicsGetCurrentContext());
    [[UIColor blackColor] setStroke];
    UIGraphicsPopContext();
    UIRectFill(CGRectMake(10, 10, 100, 100)); //

在这个示例中,画笔颜色设置为了红色,并且上下文切换为当前毫无用处的上下文。然后更改画笔的颜色为黑色,接着通过出栈使上下文回到原始状态(实际上等于什么都没做)。现在将会画一个黑色的矩形,这绝对不是你想要的。

使用UIGraphicsPushContext并不能保存上下文的当前**状态**(画笔颜色、线条宽度等),而是完全切换上下文。假设你正在当前视图上下文中绘制什么东西,这时想要在位图上下文中绘制完全不同的东西。如果要使用UIKit来进行任意绘图,你会希望保存当前的UIKit上下文,包括所有已经绘制的内容,接着切换到一个全新的绘图上下文中。这就是UIGraphicsPushContext的功能。创建完位图后,再将你的旧上下文出栈。而这就是UIGraphicsPopContext的功能。这种情况只会在要使用UIKit在新的位图上下文中绘图时才会发生。只要你使用的是Core Graphics函数,就不需要去执行上下文入栈和出栈,因为Core Graphics函数将上下文视作参数。

这是极其有用的常见操作。因为其常用性,苹果公司为其创建了一个叫做UIGraphicsBeginImageContext的快捷方式。它负责将旧的上下文入栈、为新上下文分配内存、创建新的上下文、翻转坐标系统,并使其作为当前上下文使用。它替你完成了大部分的工作。

以下是创建一张图片并使用UIGraphicsBeginImageContext返回它的示例。最终结果如图8-12所示。

MYView.m(Drawing)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    - (UIImage *)reverseImageForText:(NSString *)text {
      const size_t kImageWidth = 200;
      const size_t kImageHeight = 200;
      CGImageRef textImage = NULL;
      UIFont *font = [UIFont boldSystemFontOfSize:17.0];

      UIGraphicsBeginImageContext(CGSizeMake(kImageWidth,
                                             kImageHeight));

      [[UIColor redColor] set];
      [text drawInRect:CGRectMake(0, 0, 
                                  kImageWidth, kImageHeight)
              withFont:font];

      textImage = 
           UIGraphicsGetImageFromCurrentImageContext().CGImage;

      UIGraphicsEndImageContext();

      return [UIImage imageWithCGImage:textImage
                                 scale:1.0
                     orientation:UIImageOrientationUpMirrored];
    }

相关文章推荐

CoreGraphics之CGContextSaveGState与UIGraphicsPushContext

前言本文简书地址:http://www.jianshu.com/p/be38212c0f79 写这文章的原因是最近在写CG的时候,对于CGContextSaveGState与UIGraphicsPu...

Quartz2D绘图简介:直线/圆形/椭圆/方形以及上下文栈管理CGContextSaveGState/CGContextRestoreGState

[objc] view plain copy - (void)drawRect:(CGRect)rect {      //获得当前上下文     &...

CGContextSaveGState与CGContextRestoreGState详解

绘图第一篇 CGContextSaveGState与CGContextRestoreGState Push a copy of the current graphics state onto the ...

CGContextSaveGState与CGContextRestoreGState的作用

使用Quartz时涉及到一个图形上下文,其中图形上下文中包含一个保存过的图形状态堆栈。在Quartz创建图形上下文时,该堆栈是空的。CGContextSaveGState函数的作用是将当前图形状态推入...

CGContextRestoreGState() 的作用

Quartz2D绘图在实际的绘图过程中,对于CGContextRestoreGState() 的作用.通过查阅诸多文章, 我是这么理解的,首先,来总结下绘图的基本流程 1.获得图形上下文: let...

ios修改status bar颜色及xcode7下日志出现CGContextSaveGState: invalid context 0x0错误

设计稿要求Status bar的颜色是白色的,按照以往的做法就是: info.plist添加View controller-based status bar appearance为NO(默认是YES)...
  • IROYCN
  • IROYCN
  • 2015-10-14 11:10
  • 1864
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)