zoukankan      html  css  js  c++  java
  • 矢量图形(高效绘图 13.2)

    矢量图形

    我们用Core Graphics来绘图的一个通常原因就是只是用图片或是图层效果不能轻易地绘制出矢量图形。矢量绘图包含一下这些:

    • 任意多边形(不仅仅是一个矩形)
    • 斜线或曲线
    • 文本
    • 渐变

    举个例子,清单13.1 展示了一个基本的画线应用。这个应用将用户的触摸手势转换成一个UIBezierPath上的点,然后绘制成视图。我们在一个UIView子类DrawingView中实现了所有的绘制逻辑,这个情况下我们没有用上view controller。但是如果你喜欢你可以在view controller中实现触摸事件处理。图13.1是代码运行结果。

    清单13.1 用Core Graphics实现一个简单的绘图应用

     1 #import "DrawingView.h"
     2 
     3 @interface DrawingView ()
     4 
     5 @property (nonatomic, strong) UIBezierPath *path;
     6 
     7 @end
     8 
     9 @implementation DrawingView
    10 
    11 - (void)awakeFromNib
    12 {
    13     //create a mutable path
    14     self.path = [[UIBezierPath alloc] init];
    15     self.path.lineJoinStyle = kCGLineJoinRound;
    16     self.path.lineCapStyle = kCGLineCapRound;
    17 18     self.path.lineWidth = 5;
    19 }
    20 
    21 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    22 {
    23     //get the starting point
    24     CGPoint point = [[touches anyObject] locationInView:self];
    25 
    26     //move the path drawing cursor to the starting point
    27     [self.path moveToPoint:point];
    28 }
    29 
    30 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    31 {
    32     //get the current point
    33     CGPoint point = [[touches anyObject] locationInView:self];
    34 
    35     //add a new line segment to our path
    36     [self.path addLineToPoint:point];
    37 
    38     //redraw the view
    39     [self setNeedsDisplay];
    40 }
    41 
    42 - (void)drawRect:(CGRect)rect
    43 {
    44     //draw path
    45     [[UIColor clearColor] setFill];
    46     [[UIColor redColor] setStroke];
    47     [self.path stroke];
    48 }
    49 @end
    View Code

    图13.1 用Core Graphics做一个简单的『素描』

    这样实现的问题在于,我们画得越多,程序就会越慢。因为每次移动手指的时候都会重绘整个贝塞尔路径(UIBezierPath),随着路径越来越复杂,每次重绘的工作就会增加,直接导致了帧数的下降。看来我们需要一个更好的方法了。

    Core Animation为这些图形类型的绘制提供了专门的类,并给他们提供硬件支持(第六章『专有图层』有详细提到)。CAShapeLayer可以绘制多边形,直线和曲线。CATextLayer可以绘制文本。CAGradientLayer用来绘制渐变。这些总体上都比Core Graphics更快,同时他们也避免了创造一个寄宿图。

    如果稍微将之前的代码变动一下,用CAShapeLayer替代Core Graphics,性能就会得到提高(见清单13.2).虽然随着路径复杂性的增加,绘制性能依然会下降,但是只有当非常非常浮躁的绘制时才会感到明显的帧率差异。

    清单13.2 用CAShapeLayer重新实现绘图应用

     1 #import "DrawingView.h"
     2 #import 
     3 
     4 @interface DrawingView ()
     5 
     6 @property (nonatomic, strong) UIBezierPath *path;
     7 
     8 @end
     9 10 @implementation DrawingView
    11 
    12 + (Class)layerClass
    13 {
    14     //this makes our view create a CAShapeLayer
    15     //instead of a CALayer for its backing layer
    16     return [CAShapeLayer class];
    17 }
    18 
    19 - (void)awakeFromNib
    20 {
    21     //create a mutable path
    22     self.path = [[UIBezierPath alloc] init];
    23 
    24     //configure the layer
    25     CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
    26     shapeLayer.strokeColor = [UIColor redColor].CGColor;
    27     shapeLayer.fillColor = [UIColor clearColor].CGColor;
    28     shapeLayer.lineJoin = kCALineJoinRound;
    29     shapeLayer.lineCap = kCALineCapRound;
    30     shapeLayer.lineWidth = 5;
    31 }
    32 
    33 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    34 {
    35     //get the starting point
    36     CGPoint point = [[touches anyObject] locationInView:self];
    37 
    38     //move the path drawing cursor to the starting point
    39     [self.path moveToPoint:point];
    40 }
    41 
    42 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    43 {
    44     //get the current point
    45     CGPoint point = [[touches anyObject] locationInView:self];
    46 
    47     //add a new line segment to our path
    48     [self.path addLineToPoint:point];
    49 
    50     //update the layer with a copy of the path
    51     ((CAShapeLayer *)self.layer).path = self.path.CGPath;
    52 }
    53 @end
    View Code
  • 相关阅读:
    LuoguP1016 旅行家的预算 (贪心)
    LuoguP2254 [NOI2005]瑰丽华尔兹 (单调队列优化DP)(用记忆化过了。。。)
    LuoguP2876 [USACO07JAN]解决问题Problem Solving (区间DP)(未完成)
    Luogu3275 [SCOI2011]糖果 (差分约束)
    Luogu1993 小K的农场 (差分约束)
    Luogu4427 [BJOI2018]求和 (树上差分)
    LuoguP1516 青蛙的约会 (Exgcd)
    POJ3903Stock Exchange (LIS)
    LuoguP1020 导弹拦截 (LIS)
    线性筛
  • 原文地址:https://www.cnblogs.com/EchoHG/p/7630190.html
Copyright © 2011-2022 走看看