zoukankan      html  css  js  c++  java
  • CoreGraphic

    1. public func UIGraphicsBeginImageContextWithOptions( size: CGSize, opaque: Bool, _ scale: CGFloat)

      size是要截图的大小,opaque是否不透明,不透明生成的图片小点,scale代表比例,1倍按照size的分辨率进行输出,n倍乘以n,如果需要输出当前设备的分辨率,使用UIScreen.main.scale来获取最合适的比例,也可以直接传0,系统会自动获取合适的scale。沃日。这么简单。。。如果是录视频的话,就得用UIScreen.main.scale

    2. CG框架的内存需要我们手动管理,记得结束的时候释放内存,比如UIGraphicsEndImageContext();

    3. 1
      2
      3
      4
      5
      // 同时设置fill和stroke的颜色
      UIColor.green.set();
      // 下面俩个分别只设置一种
      UIColor.green.setStroke();
      UIColor.green.setFill();
    4. 如果是用UIKit方法获取到的context,那么坐标系原点在左上,否则用CG方法获取到的context坐标系原点在左下.调整左下坐标系到左上坐标系

      1
      2
      3
      4
      5
      6
      7
      CGContextRef context = UIGraphicsGetCurrentContext(); if (context == NULL)
      {
      NSLog(@"Error: No context to flip");
      return; }
      CGAffineTransform transform = CGAffineTransformIdentity;
      transform = CGAffineTransformScale(transform, 1.0f, -1.0f);
      transform = CGAffineTransformTranslate(transform, 0.0f, -size.height); CGContextConcatCTM(context, transform);
    5. 画虚线方法的各参数含义

      1
      2
      3
      4
      5
      6
      7
      8
      let path = UIBezierPath(rect: CGRect(x: 50, y: 50, 100, height: 100));
      UIColor.green.set();
      // 数组的值代表第一个线宽为6然后第二个线宽为2,第三个线宽为5.以此类推.
      // 空白也算一个线段,也参与计算宽度.所以如下所示就是第一个实线宽度为6,然后接下来的空白宽度为2,然后接下来的实线宽度为5然后接下来的空白宽度为6...以此类推
      let dashes:[CGFloat] = [6.0, 2.0, 5.0];
      // count要等于dashes数组的长度,phase表示跳过多少个点.如上数组所示,6就是6个点
      path.setLineDash(dashes, count: 3, phase: 0);
      path.stroke();
    6. 坐标系转换方法例如下面一种

      1
      2
      CGPoint convertedPoint =
      [outerView convertPoint:samplePoint fromView:grayView];

      有一个前提,就是两个View必须在同一个Window中.

    7. Transform

      transform形变的原点都是(0,0)如果想要以中点进行形变,需要改变这个默认原点

      1
      context?.translateBy(x: center.x, y: center.y);
    8. 如果绘图的context不是UIGraphicsBeginImageContextWithOptions(rect.size, true, 0.0);那么所绘制的一切用let image = UIGraphicsGetImageFromCurrentImageContext();这个方法截图是只是一张黑色图片,相反如果绘图的context时ImageContext,那么截图可以正常显示出来,但是真实的屏幕上则只显示黑色。

      为了截图不是黑色的图

      1
      2
      3
      4
      UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, 0.0);
      view.layer.render(in: UIGraphicsGetCurrentContext()!);
      let image2 = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
    9. UIRectFill:给自定rect填充一个矩形 UIRectFrame:给自定rect画一个边框

    10. path.usesEvenOddFillRule. usesEvenOddFillRule顾名思义就是even-奇 odd-偶,奇偶规则

    11. 画阴影

    1
    2
    CGContextSetShadowWithColor(context, CGSizeMake(5, 5), 0, [UIColor greenColor].CGColor);
    1. 对文字的动画

      关键点在于用CoreText创建出文字的路径,CoreText提供了对应的方法,代码如下

    1
    2
    大专栏  CoreGraphiclass="line">3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    let letters = CGMutablePath();
    // 此处font作为attribute传入属性字符串,然后在之后的遍历中取出来使用
    let ctfont = CTFontCreateWithName(font.fontName as CFString?, font.pointSize, nil);
    let attr = NSAttributedString(string: text, attributes: [kCTFontAttributeName as String : ctfont]);
    let line = CTLineCreateWithAttributedString(attr);
    let runArray = CTLineGetGlyphRuns(line);
    for runIndex in 0..<CFArrayGetCount(runArray) {
    let run: CTRun = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self);
    let dictRef: CFDictionary = unsafeBitCast(CTRunGetAttributes(run), to: CFDictionary.self);
    let dict :NSDictionary = dictRef as NSDictionary;
    let runFont = dict[kCTFontAttributeName as String] as! CTFont;
    // 取出每一个字形。来创路径
    for runGlyphIndex in 0..<CTRunGetGlyphCount(run) {
    let thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
    var glyph = CGGlyph();
    var position = CGPoint.zero;
    CTRunGetGlyphs(run, thisGlyphRange, &glyph);
    CTRunGetPositions(run, thisGlyphRange, &position);
    let letter = CTFontCreatePathForGlyph(runFont, glyph, nil);
    let t = CGAffineTransform.init(translationX: position.x, y: position.y);
    letters.addPath(letter!, transform: t);
    }
    }
    1. TransparencyLayer透明图层.待研究

    2. layerx的drawInContext方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // 如果在此方法内不将ctx压入栈中会导致接下去的bezeirPath画图方法失效。原因是rectPath.stroke()
      // 是在当前ctx生效的,可是如果不压入栈中,当前的ctx就会为空
      UIGraphicsPushContext(ctx);
      let rectPath = UIBezierPath(rect: self.outsideRect);
      UIColor.black.setStroke();
      let dash = [5.0.cgfloatValue, 5.0.cgfloatValue];
      rectPath.lineWidth = 1.0;
      rectPath.setLineDash(dash, count: 2, phase: 0);
      rectPath.stroke();
      UIGraphicsPushContext(ctx);

      如果不选择UIGraphicsPushContext(ctx);这种方法,那么需要用到C的API画图

      1
      2
      3
      4
      5
      6
      7
      let rectPath = UIBezierPath(rect: self.outsideRect);
      ctx.addPath(rectPath.cgPath);
      ctx.setStrokeColor(UIColor.black.cgColor);
      ctx.setLineWidth(1.0);
      let dash = [5.0.cgfloatValue, 5.0.cgfloatValue];
      ctx.setLineDash(phase: 0, lengths: dash);
      ctx.strokePath();

      这样就不会依赖UIGraphicsGetCurrentContext.

  • 相关阅读:
    testDecoration
    python装饰器详解
    开闭原则, 对扩展开放、对修改关闭
    使用元类 编写ORM
    Python 实现累加计数的几种方法
    python 查找目录下 文件名中含有某字符串的文件
    android应用程序的混淆打包规范
    自定义Tabs
    android-Service
    Loader异步装载器
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12284923.html
Copyright © 2011-2022 走看看