核心绘图——Core Graphics

Core Graphics的简介与概述(一)   简介: Core Graphics是Quartz 2D的一个高级绘图引擎,常用与iOS,tvOS,macOS的图形绘制应用开发。Core Graphics是对底层C语言的一个简单封装,其中提供大量的低层次,轻量级的2D渲染API。 Core GraphicsAPI简单易于使用,并且提供了强大的功能访问,如透明层,基于路径的涂层绘制,屏幕外呈现,高级色彩管理,抗锯齿已经PDF文档的生成解析... 阅读详情

一. Core Graphics简介

  1. Core Graphics是一个基于C的绘图专用的API族,它经常被称为QuartZ或QuartZ 2D,是一个二维绘图引擎,同时支持iOS和Mac系统。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变。
    提示:
    引擎:经过包装的函数库,方便开发者使用。QuartZ 2D是苹果帮封装的一套绘图的函数库。
    同时支持iOS和Mac系统:用QuartZ 2D写的同一份代码,既可以运行在iphone上又可以运行在mac上,可以跨平台开发。

  2. QuartZ 2D在开发中比较常用的是截屏/裁剪/自定义UI控件,QuartZ 2D在iOS开发中的主要价值是自定义UI控件

  3. QuartZ 2D能完成的工作
    (1).绘制图形: 线条\三角形\矩形\圆\弧等
    (2).绘制文字
    (3).绘制\生成图片(图像)
    (4).读取\生成PDF
    (5).截图\裁剪图片
    (6).自定义UI控件

二. 图形上下文(Graphics Context)

  1. 图形上下文是一个CGContextRef类型的数据,图形上下文相当于画板,用于封装绘图信息(画了什么)和绘图状态(线条大小、颜色等),它决定绘制的输出目标(绘制到什么地方去),目标可以是PDF文件、bitmap或者显示器的窗口。

  2. 相同的一套绘图序列,指定不同的图形上下文,就可将相同的图像绘制到不同的目标上,目标可以是PDF文件、bitmap或者显示器的窗口。

  3. QuartZ 2D提供了 5 种类型的图形上下文:Bitmap Graphics Context、PDF Graphics Context、Window Graphics Context、Layer Context、Post Graphics Context。

  4. 在UIView中,系统会默认创建一个Layer Graphics Context,它对应UIView的layer属性,该图形上下文可以在drawRect:方法中获取,开发者只能获取,不能自己重新创建,在该图层上下文中绘制的图形,最终会通过CALayer显示出来。因此,View之所以能显示东西,完全是因为它内部的layer。

三. 图形上下文的图形状态堆栈

图形上下文中包含一个保存过的图形状态堆栈。在QuartZ 2D创建图形上下文时,该堆栈是空的。
CGContextSaveGState()函数的作用是将当前图形状态推入堆栈。之后,您对图形状态所做的修改会影响随后的描画操作,但不影响存储在堆栈中的拷贝。在修改完成后,您可以通过CGContextRestoreGState()函数把堆栈顶部的状态弹出,返回到之前的图形状态。这种推入和弹出的方式是回到之前图形状态的快速方法,避免逐个撤消所有的状态修改;这也是将某些状态(比如裁剪路径)恢复到原有设置的唯一方式。

四. UIView和CALayer的区别

  1. 对于继承
    UIView —> UIResponder —> NSObject
    CALayer —> NSObject

  2. 对于响应用户事件
    UIView继承自UIResponder,UIResponder是用来响应事件的,所以UIView可以响应事件
    CALayer直接继承于NSObject,所以CALayer不能响应事件

  3. 对于所属框架
    UIView是在/System/Library/Frameworks/UIKit.framework中定义,UIKit主要是用来构建用户界面,并且是可以响应事件的
    CALayer是在/System/Library/Frameworks/QuartzCore.framework定义,2D图像绘制都是通过QuartzCore.framework实现的

  4. 对于基本属性
    UIView:position、size、transform
    CALayer:position、size、transform、animations

  5. 总结
    UIView相比CALayer最大区别是UIView可以响应用户事件,而CALayer不可以。UIView侧重于对显示内容的管理,CALayer侧重于对内容的绘制。对于UIView所管理的内容,显示任何图形都会受到CALayer的影响。UIView依赖于CALayer提供的内容,CALayer依赖于UIView提供的容器来显示绘制的内容。UIView与CALayer都有树状层级结构,CALayer内部有SubLayers,UIView内部也有SubViews。

五. UIView的显示原理

因为UIView依赖于CALayer提供的内容,而CALayer又依赖于UIView提供的容器来显示绘制的内容,所以UIView的显示可以说是CALayer要显示绘制的图形。当要显示时,CALayer会准备好一个CGContextRef(图形上下文),然后调用它的delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象,在drawLayer:inContext:方法中UIView又会调用自己的drawRect:方法。

我们可以把UIView的显示比作“在电脑上使用播放器播放U盘上得电影”,播放器相当于UIView,视频解码器相当于CALayer,U盘相当于CGContextRef,电影相当于绘制的图形信息。不同的图形上下文可以想象成不同接口的U盘。

注意:当我们需要绘图到根层上时,一般在drawRect:方法中绘制,不建议在drawLayer:inContext:方法中绘图

六. 绘图的步骤

方法一:最原始的绘图方式

  1. 获取当前控件的图形上下文
  2. 描述绘画内容
    a. 创建图形路径
    b. 创建图形起始点
    c. 添加图形的终点
  3. 把绘画内容添加到图形上下文
  4. 设置图形上下文的状态(线宽、颜色等)
  5. 渲染图形上下文
- (void)drawRect:(CGRect)rect {
// 1. 获取当前控件的图形上下文
    // CG:表示这个类在CoreGraphics框架里  Ref:引用
    CGContextRef context = UIGraphicsGetCurrentContext();
// 2. 描述绘画内容
//    a. 创建图形路径
    CGMutablePathRef path = CGPathCreateMutable();
//    b. 创建图形起始点
    CGPathMoveToPoint(path, NULL, 50, 50);
//    c. 添加图形的终点
    CGPathAddLineToPoint(path, NULL, 200, 50);
// 3. 把绘画内容添加到图形上下文
    CGContextAddPath(context, path);
// 4. 设置图形上下文的状态(线宽、颜色等)
    CGContextSetLineWidth(context, 5);
    CGContextSetRGBStrokeColor(context, 0, 1, 0, 1);
// 5. 渲染图形上下文 
    CGContextStrokePath(context);
}

解析:
1.drawRect方法是在当前控件要显示的时候才去调用,并且drawRect方法只能系统调用,不能手动调用,手动调用setNeedDispplay方法或setNeedsDisplayInRect:方法,系统才会去调用drawRect。

系统默认:viewWillAppear —> drawRect —> viewDidAppear
手动调用:setNeedDispplay —> drawRect

2.- (void)drawRect:(CGRect)rect;中的rect的值是当前控件的bounds值。

3.描述绘画内容相当于描述图形的路径,其实也就是设置图形的各个关键点,但是还没有真正画线,只有起点和终点绘制的图形是一条直线,画线是在view要显示的时候才进行,但路径添加到上下文后必须渲染上下文,不然图形不会显示在view上。

获取图形上下文 —> 创建图形路径 —> 设置路径 —> 设置上下文状态 —> 路径添加到上下文 —> 渲染上下文 —> 在view上显示

4.一条路径连续多次调用addLineToPoint函数添加点,它的路径是拼接的,默认下一条线的起点是上一条线的终点。

5.当要画多根不连续的线,方法一:创建不同的路径再添加线段需要的点,方法二:同一个路径,按步骤画完第一条线,第二条线是重新设置起始点再设置需要的点。

6.可以创建多个路径,多个路径可以绘制多个图形,但是使用原始方法绘图不能单独管理图形的状态(线条、颜色等)。

方法二:使用上下文直接绘图

注意:不用创建路径,也不需要把绘图内容添加到图形上下文,因为图形上下文封装了这些步骤。

  1. 获取当前控件的图形上下文
  2. 描述绘画内容
    a. 创建图形起始点
    b. 添加图形的终点
  3. 设置图形上下文的状态(线宽、颜色等)
  4. 渲染图形上下文
- (void)drawRect:(CGRect)rect {  
    // 1. 获取当前控件的图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 描述绘画内容
    // a. 创建图形起始点
    CGContextMoveToPoint(context, 20, 50);
    // b. 添加图形的终点
    CGContextAddLineToPoint(context, 200, 150);
    CGContextAddLineToPoint(context, 200, 55);

    // 3. 设置图形上下文的状态(线宽、颜色等)
    CGContextSetLineWidth(context, 5);
    CGContextSetCMYKStrokeColor(context, 0, 1, 1, 0, 1);

    // 4. 渲染图形上下文
    CGContextStrokePath(context);  
}

方法三:贝瑟尔路径(UIBezierPath)绘图

提示:

  1. UIKit已经封装了一些绘图的功能:UIBezierPath,里面封装了很多东西,可以帮我画一些基本的线段,矩形,圆等等,一般开发中用贝塞尔路径绘图。
  2. CGPath转换:UIKit框架转CoreGraphics直接 .CGPath 就能转换
    优点: 用UIBezierPath 画多根不连接的线,可以管理各个线的状态
    缺点: UIBezierPath 不能画曲线

注意:
使用贝瑟尔路径绘图只能在drawRect里进行,因为底层要用到上下文,图形上下文只能在drawRect里获取,不能在其他方法里面绘图,比如:不能在awakeFromNib里绘图!

  1. 创建贝瑟尔路径
  2. 描述绘画内容
    a. 创建图形起始点(moveToPoint)
    b. 添加图形的终点(addLineToPoint)
  3. 设置路径状态
  4. 绘制路径
- (void)drawRect:(CGRect)rect {

    // 1. 创建贝瑟尔路径
    UIBezierPath *path = [UIBezierPath bezierPath];

    // 2. 设置起点
    [path moveToPoint:CGPointMake(20, 20)];

    // 3. 设置终点
    [path addLineToPoint:CGPointMake(80, 150)];

    // 4. 设置路径状态
    // 设置颜色
    [[UIColor redColor] set];
    // 设置线宽
    [path setLineWidth:5];

    // 4. 绘制路径
    [path stroke];



    // 1. 创建贝瑟尔路径
    UIBezierPath *path1 = [UIBezierPath bezierPath];

    // 2. 设置起点
    [path1 moveToPoint:CGPointMake(50, 20)];

    // 3. 设置拐点
    [path1 addLineToPoint:CGPointMake(200, 100)];

    // 3. 设置终点
    [path1 addLineToPoint:CGPointMake(50, 230)];

    // 4. 设置路径状态
    // 设置颜色
    [[UIColor blueColor] set];
    // 设置线宽
    [path1 setLineWidth:15];
     // 设置连接样式
    [path1 setLineJoinStyle:kCGLineJoinRound];
    // 设置顶角样式
    [path1 setLineCapStyle:kCGLineCapRound];

    // 4. 绘制路径
    [path1 stroke];

}

七. 绘制曲线

方法一:最原始绘图方法

  1. 获取当前控件的图形上下文
  2. 描述绘画图形内容
    a. 获取图形路径
    b. 添加起始点
    c. 添加控制点和终点
  3. 把绘制图形内容添加到图形上下文
  4. 设置图形上下文状态
  5. 渲染图形上下文
- (void)drawRect:(CGRect)rect {

    // 1. 获取当前控件的图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 描述绘画图形内容
    // a. 获取图形路径
    CGMutablePathRef path = CGPathCreateMutable();
    // b. 添加起始点
    CGPathMoveToPoint(path, NULL, 0, 0);
    // C. 添加控制点和终点,控制点(150,150)、终点(0,250)
    CGPathAddQuadCurveToPoint(path, NULL, 250, 150, 0, 250);

    // 3. 把绘制图形内容添加到图形上下文
    CGContextAddPath(context, path);

    // 4. 设置图形上下文状态
    // 设置颜色
    [[UIColor redColor] set];
    // 设置线宽
    CGContextSetLineWidth(context, 10);

    // 5. 渲染图形上下文
    CGContextStrokePath(context);
}

方法二:使用上下文直接绘图

  1. 获取当前控件的图形上下文
  2. 描述绘画图形内容
    a. 创建图形起始点
    b. 添加控制点和终点
  3. 设置图形上下文状态
  4. 渲染图形上下文
- (void)drawRect:(CGRect)rect {

    // 1. 获取当前控件的图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 2. 描述绘画图形内容
    // a. 创建图形起始点
    CGContextMoveToPoint(context, 0, 0);
    // b. 添加控制点和终点,控制点(300,200),终点(0,250)
    CGContextAddQuadCurveToPoint(context, 300, 200, 0, 250);

    // 3. 设置图形上下文状态
    // 设置颜色
    [[UIColor redColor] set];
    // 设置线宽
    CGContextSetLineWidth(context, 10);

    // 4. 渲染图形上下文
    CGContextStrokePath(context);
}

八. 绘制图形

常见问题:
1. 关闭路径closePath:从路径的终点连接到起点
2. 填充路径CGContextFillPath:有了封闭的路径就能填充。
3. 设置填充颜色 [[UIColor blueColor] setFill];
4. 设置描边颜色 [[UIColor redColor] setStroke];
5. 不显示描边颜色,为什么?没有设置线宽
6. 设置线宽,还是不显示,为什么?因为绘制路径不对。
7. 即填充又描边CGContextDrawPath:kCGPathFillStroke。
8. 圆的起点在圆右边水平线

(一). 圆角矩形

    // RoundedRect: 坐标与宽高
    // cornerRadius: 角半径
    UIBezierPath *oblongPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 150) cornerRadius:100];
    // 颜色
    [[UIColor redColor] set];
    // 填充
    [oblongPath fill];

(二). 扇形

    // 扇形
    // Center:圆心
    // startAngle:弧度
    // clockwise:YES:顺时针 NO:逆时针
    CGPoint center = CGPointMake(100, 100);
    UIBezierPath *sectorPath = [UIBezierPath bezierPathWithArcCenter:center radius:50 startAngle:0 endAngle:M_PI clockwise:YES];

    // 从终点连线到圆心
    [sectorPath addLineToPoint:center];

    // 颜色
    [[UIColor blueColor] set];

//    // 关闭路径,从终点连线到起始点
//    [sectorPath closePath];
//    // 描边
//    [sectorPath stroke];

    // 填充:必须是一个完整的封闭路径,默认就会自动关闭路径
    [sectorPath fill];

九. 上下文的状态栈

- (void)drawRect:(CGRect)rect {

    // 获取上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 描述图形内容
    // 第一根线
    UIBezierPath *path1 = [UIBezierPath bezierPath];

    [path1 moveToPoint:CGPointMake(50, 10)];
    [path1 addLineToPoint:CGPointMake(50, 150)];

    // 把第一根添加到上下文
    CGContextAddPath(context, path1.CGPath);

    // 保存一份初始的上下文状态
    CGContextSaveGState(context);

    // 设置上下文状态
    [[UIColor redColor] set];
    CGContextSetLineWidth(context, 5);

    // 渲染上下文
    CGContextStrokePath(context);


    // 第二根线
    UIBezierPath *path2 = [UIBezierPath bezierPath];

    [path2 moveToPoint:CGPointMake(100, 10)];
    [path2 addLineToPoint:CGPointMake(100, 150)];

    // 添加到上下文
    CGContextAddPath(context, path2.CGPath);

    // 还原上下文状态
    CGContextRestoreGState(context);

    // 渲染上下文
    CGContextStrokePath(context);

}

十. 上下文的矩阵操作

- (void)drawRect:(CGRect)rect {

    // 获取上下文
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 创建路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 50, 100)];

    // 矩阵操作
    // 移动
    CGContextTranslateCTM(context, 100, 100);
    // 缩放
    CGContextScaleCTM(context, 1, 2);
    // 旋转
    CGContextRotateCTM(context, M_PI_4);


    // 把路径添加到上下文
    CGContextAddPath(context, path.CGPath);

    // 设置颜色
    [[UIColor blueColor] set];

    // 渲染上下文
    CGContextStrokePath(context);

}

十一. 图片水印

  1. 开启位图上下文
  2. 描述绘画内容
    a. 绘制图片
    b. 绘制文字
    C. 绘制图形等
  3. 从位图上下文获取生成的图片
  4. 关闭位图上下文
- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建图片
    UIImage *logoImage = [UIImage imageNamed:@"小黄人"];

    // 1. 开启位图上下文
    // 注意: 位图上下文跟view无关联,所以不需要在drawRect中获取上下文
    // size: 位图上下文的尺寸(绘制出新图片的尺寸)
    // opaque: 是否透明,YES:不透明  NO:透明,通常设置成透明的上下文
    // scale: 缩放上下文,取值0表示不缩放,通常不需要缩放上下文
    UIGraphicsBeginImageContextWithOptions(logoImage.size, NO, 0);

    // 2. 描述绘画内容

    // 绘制原生图片
    [logoImage drawAtPoint:CGPointZero];

    // 绘制文字
    NSString *logo = @"小黄人";
    // 创建字典属性
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName] = [UIColor redColor];
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:20];
    [logo drawAtPoint:CGPointMake(51, 27) withAttributes:dict];

    // 绘制图形
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(30, 30, 20, 20)];
    [[UIColor redColor] set];
    [path fill];

    // 3. 从上下文获取生成的图片
    _logoImage.image = UIGraphicsGetImageFromCurrentImageContext();


    // 4. 关闭位图上下文
    UIGraphicsEndImageContext();

}

提示:
1. 位图上下文跟view无关联,所以不需要在drawRect中获取上下文
2. UIGraphicsGetCurrentContext()函数可以获取的不同类型的上下文,CGContextRef变量可以指向不同类型上下文
3. 在位图上下文上绘制图形,必须获取位图上下文生成的图片,再显示图片才可以看见绘制的图形
4. 位图上下文的获取方式跟layer上下文不一样,位图上下文需要手动创建

十二. 图片裁剪

  1. 开启位图上下文
  2. 设置裁剪区
  3. 绘制图片
  4. 从位图上下文获取生成的图片
  5. 关闭位图上下文
- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建图片
    UIImage *image = [UIImage imageNamed:@"阿狸头像"];

    // 1. 开启上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);

    // 2. 设置裁剪区
    // 创建图形路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    // 把图形路径设置为裁剪区
    [path addClip];

    // 3. 绘制图形
    [image drawAtPoint:CGPointZero];

    // 4. 从位图上下文获取图片
    _SJMImage.image = UIGraphicsGetImageFromCurrentImageContext();


    // 5. 关闭上下文
    UIGraphicsEndImageContext();

}

十三. 屏幕截屏

  1. 开启一个位图上下文
  2. 获取位图上下文
  3. 把屏幕上的图层渲染到图形上下文
  4. 从位图上下文获取图片
  5. 关闭上下文
  6. 存储图片
- (void)viewDidLoad {

    // 1. 开启一个位图上下文
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);

    // 2. 获取位图上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // 3. 把屏幕上的图层渲染到图形上下文
    [self.view.layer renderInContext:ctx];

    // 4. 从位图上下文获取图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    // 5. 关闭上下文
    UIGraphicsEndImageContext();

    // 6. 存储图片
    // image转data
    // compressionQuality:图片质量  1:最高质量
    NSData *data = UIImageJPEGRepresentation(image,1);
    [data writeToFile:@"/Users/SJM/Desktop/view.png" atomically:YES];

}

十四. 提高描画的性能

  1. 合成不透明的视图所需要的开销比合成部分透明的视图要少得多。一个不透明的视图必须不包含任何透明的内容,且视图的opaque属性必须设置为YES。
  2. 如果一个PNG图像的每个像素都是不透明的,则将其alpha通道删除可以避免对包含该图像的图层进行融合操作,从而很大程度上简化了该图像的合成,提高描画的性能。
  3. 在每个更新周期中,您应该只更新视图中真正发生变化的部分。如果您使用UIView的drawRect:方法来进行描画,则要通过传给该方法的更新矩形来限制描画的范围。对于基于OpenGL的描画,您必须自行跟踪更新区域。
  4. 应该避免在滚动过程种创建新的视图。创建新视图的开销会减少用于更新屏幕的时间,因而导致滚动不平滑。
  5. 缺省情况下,在调用drawRect:方法对视图的某个区域进行更新之前,UIKit会清除该区域对应的上下文缓冲区。如果您对视图的滚动事件进行响应,则在滚动过程中反复清除缓冲区的开销是很大的。为了禁止这种行为,可以将clearsContextBeforeDrawing属性设置为NO。
  6. 改变图形状态需要窗口服务器的参与。如果您要描画的内容使用类似的图形状态,则尽可能将这些内容一起描画,以减少需要改变的状态。

十五. 保持图像的质量

  1. 为用户界面提供高品质的图像应该是设计工作中的重点之一。图像是一种合理而有效的显示复杂图形的方法,任何合适的地方都可以使用。在为应用程序创建图像的时候,请记住下面的原则:
  2. 使用PNG格式的图像。PNG格式可以提供高品质的图像内容,是iPhone OS系统上推荐的图像格式。另外,iPhone OS对PNG图像的描画路径是经过优化的,通常比其它格式具有更高的效率。
  3. 创建大小合适的图像,避免在显示时调整尺寸。如果您计划使用特定尺寸的图像,则在创建图像资源时,务必使用相同的尺寸。不要创建一个大的图像,然后再缩小,因为缩放需要额外的CPU开销,而且需要进行插值。如果您需要以不同的尺寸显示图像,则请包含多个版本的图像,并选择与目标尺寸相对接近的图像来进行缩放。

十六. CGContextDrawImage使用提示

使用CGContextDrawImage()函数来直接描画位图,则在缺省情况下,图像数据会上下倒置,因为Quartz图像假定坐标系统的原点在左下角,且坐标轴的正向是向上和向右。虽然您可以在描画之前对其进行转换,但是将Quartz图像包装为一个
UIImage

大数据采集技术全景图:从概念到主流工具实战解析 本文全面解析大数据采集技术,从概念到主流工具实战应用。详细介绍网络爬虫、日志采集和数据库采集等核心技术,并结合电商用户行为分析系统案例,展示如何高效实施大数据采集。文章还探讨了实时采集技术的前沿趋势与选型建议,帮助企业在海量数据时代构建高效的数据采集体系。 阅读详情

相关推荐

Core Graphics核心绘图 ( 一)

1)什么是 Graphics(核心绘图) Core Graphics 是核心绘图框架,其中的 Quartz 2D API 专门提供图形绘制工作 所有 UIKit 的底层渲染工作都是由 Core Graphics 完成的 由于与 UIKit 绑定的非常紧密,因此开发时,引入 UIKit 框架的同时会自动引入 Core Graphics框架2)什么是 Quartz 2D? 是一个二维绘图引擎 同时支持i

土豆萝卜的博客 1010

Core Graphics框架 : 一个让程序猿成为视觉设计师的框架

Core Graphics简介 说Core Graphics框架之前,我们首先要先说一下,在iOS中绘制图形的方式,其形式主要有三种. 1.创建一个UI视图,并且使用"drawRect:"方法添加到Quartz 2D绘制代码中,也就是今天所要说的Core Graphics框架. 2.使用Core Animation层,并且通过委托方法想Core Animation层提供图形内容. 3.通过 OpenGL ES 渲染图形 其结构图如下所示.从图中我们看到的是是不管使用者还是开发者最容易接触到的先..

得不到的永远是骚栋. 1162

Core Graphics核心绘图 ( 二)

上一篇讲了一点core Graplics的基础东西,这一篇继续讲它的一些属性。1 线条属性 线宽:CGContextSetLineWidth 连接样式:CGContextSetLineJoin 顶点样式:CGContextSetLineCap 2 绘制虚线 CGContextSetLineDash(ctx, 0, lengths, sizeof(lengths) / sizeof(leng

土豆萝卜的博客 412

CoreGraphics详解

iOS开发中我们经常会使用UIButton,UILabel等,这些简单的api可以让我们很快完成常规界面的开发。如果碰到一些需要自定义的界面,我们肯定需要自己绘制。今天就学习记录下iOS中关于绘制的框架CoreGraphics。Core Graphics是基于Quartz 2D的一个高级绘图引擎,常用于iOS,tvOS,macOS的图形绘制应用开发。Core Graphics是对底层C语言的一个简单封装,其中提供大量的低层次,轻量级的2D渲染API。###系统的绘图框架UIKit。

liuxinzhongliubin的博客 1519

MATLAB绘图进阶:从基础函数到专业可视化实战指南

数据可视化是科学计算与工程分析中的核心环节,其本质是将抽象数据转化为直观图形,以揭示规律、传达信息。其原理基于图形对象系统,通过分层结构(如坐标轴、线条、文本等对象)实现对图表元素的精准控制。掌握这一技术能极大提升科研论文、工程报告的说服力与沟通效率,广泛应用于算法结果展示、仿真对比、数据分布分析等场景。本文聚焦于MATLAB这一主流工具,深入解析其**图形对象体系**与**高级绘图技巧**,涵盖从二维线图、三维曲面到复杂布局、图形导出的全流程实战要点,帮助用户实现从‘能画图’到‘画好图’的跨越。

weixin_30268071的博客 434

iOS图形绘制框架全解析:UIBezierPath、Core Graphics与OpenGL ES

图形绘制是移动应用开发中的核心技术,iOS平台提供了多层次的图形渲染解决方案。从基础的UIBezierPath到专业的Core Graphics,再到高性能的OpenGL ES,每个框架都有其特定的应用场景和技术优势。UIBezierPath作为UIKit的高级封装,适合快速实现简单矢量图形;Core Graphics提供完整的2D渲染能力,支持渐变、混合模式等高级特性;OpenGL ES则是3D图形和游戏开发的首选,直接操作GPU实现硬件加速。理解这些框架的层级关系和性能特点,能够帮助开发者在不同场景下做

weixin_34005090的博客 280

Core Graphics核心绘图 ( 三) --贝塞尔曲线

1)UIBezierPath(贝塞尔曲线) 在自定义View的时候,可以使用贝塞尔曲线(UIBezierPath)类来实现直线和曲线的绘制和渲染,起初是使用贝塞尔曲线是定义路径的几何形状。贝塞尔曲线可以定义矩形、椭圆和圆形等简单形状或者是融合直线和曲线的多边形,并且可以调用该类中的一些方法在当前上下文中渲染定义完的路径形状。 1:画矩形+(instancetype)bezierPathWithR

土豆萝卜的博客 968

24、CoreGraphics绘图全解析

本文全面解析了CoreGraphics绘图技术,从基础概念如画家模型和颜色理论,到实际绘图工具如路径、图元、文本、图像、图案和阴影的使用进行了详细讲解。文章还介绍了绘图上下文管理、坐标系统转换以及绘图状态的处理,帮助开发者掌握CoreGraphics的强大功能,并实现复杂的绘图效果。

motor的博客 96

复习Core Graphics-1

1.UIGraphicsBeginImageContextWithOptions(targetSize,isOpaue,deviceScale);  UIGraphicsGetCurrentContext(); CGUIGraphicsGetImageFromCurrentContext();  UIGraphicsEndImageContext(); 2.CGColorSpaceCreateD

xiaoyin的专栏 352

15、使用Core Graphics绘图

本文深入探讨了iOS开发中的Core Graphics框架,特别是Quartz 2D部分,涵盖绘图上下文、坐标系统、颜色指定、路径创建、描边路径、矩形与椭圆绘制等核心概念。同时介绍了如何通过减少重绘区域和使用缓存来优化绘图性能,并展示了如何实现渐变、虚线模式等高级效果。最后提供了QuartzFun应用程序的完整代码示例,帮助开发者掌握自定义绘图技术。

cream的博客 249

dreamerv3复现教程

由于dreamerv3存在很多版本冲突问题,所以很难直接使用和复现。

无人机飞啊飞啊飞 2832

iOS绘图教程 (转,拷贝以记录)

本文是《Programming iOS5》中Drawing一章的翻译,考虑到主题完整性,在翻译过程中我加入了一些书中没有涉及到的内容。希望本文能够对你有所帮助。 转自:http://www.dkankan.com/archives/6837 本文由海水的味道翻译,转载请注明译者和出处,请勿用于商业用途! Core Graphics Framework是一套基于C的API框架,...

237

Flotherm XT学习历程

大家好,通过半年的热仿真软件学习使用,最终发现最好用,最好上手的软件就是Flotherm XT,对新手非常友好,但由于软件近几年才发布,网上教程非常少,后面我将在这里持续分析软件使用心得,和大家一起学习。

xiaoredred的博客 6258

李洪强iOS经典面试题143-绘图与动画

李洪强iOS经典面试题143-绘图与动画 绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation 属性解析:keyPath:通过指定CALayer的一个属性名称为keyPath...

aaa1231722的博客 119

从实验室到生产线:Qwen3-Omni后训练技术在实际业务中的落地挑战

本文探讨了Qwen3-Omni后训练技术在实际业务中的落地挑战,重点分析了多模态AI在工业应用中的关键问题与解决方案。通过金融风控、跨境电商等场景案例,揭示了通用模型与垂直需求的矛盾,并提供了知识蒸馏、语音合成优化等实战经验,助力企业实现技术到业务的转化。

weixin_29035147的博客 266

《点亮创新灯塔!AI应用架构师与中小学初等教育AI智能体,共筑智能化教育辅助创新灯塔》

中小学AI智能体,是基于AI技术,能感知教育场景、理解教育规律、辅助教师教学和学生学习的智能系统。做老师“做不了”的事:比如5分钟批改45本作业,精准统计每个学生的易错点;做老师“做不好”的事:比如根据学生的学习风格(视觉/听觉/动觉)推荐个性化内容;绝不做老师“该做的事”:比如情感交流、价值观引导、创意教学设计——这些“人的温度”,AI永远无法替代。我是林宇,资深AI应用架构师,专注教育AI领域8年,参与过10多个中小学AI智能体项目,曾为北京、上海、深圳等城市的100多所学校提供AI教育解决方案。

Java大师兄的博客 433

iOS绘图教程

转自:http://www.cocoachina.com/industry/20140115/7703.html 本文是《Programming iOS5》中Drawing一章的翻译,考虑到主题完整性,翻译版本中加入了一些书中未涉及到的内容。希望本文能够对你有所帮助。(本文由海水的味道翻译整理,转载请注明译者和出处,请勿用于商业用途!原文)   Core Graphics Frame

zhanglizhi111的博客 647

保姆级教程:SAP ABAPer如何为VF01销售发票和MIRO发票校验配置凭证替代(含AC_DOCUMENT BADI完整代码示例)

本文详细解析了SAP ABAP中通过AC_DOCUMENT BADI实现VF01销售发票和MIRO发票校验的凭证替代技术。从技术选型到BADI实施步骤,再到核心逻辑代码示例,为ABAP开发者提供了一套完整的解决方案,帮助应对财务部门复杂的业务需求。

weixin_30421809的博客 349

iOS图形绘制框架:UIBezierPath、Core Graphics与OpenGL ES详解

图形绘制是移动应用开发中的核心技术,涉及矢量路径、2D渲染和3D图形处理等多个层面。在iOS生态中,系统提供了从简单到复杂的三层绘图框架:UIBezierPath作为UIKit封装的轻量级工具,适合处理基础矢量图形;Core Graphics作为Quartz 2D引擎的底层实现,支持高级2D效果和离屏渲染;OpenGL ES则提供跨平台的GPU加速接口,专为高性能图形处理设计。这些技术在UI优化、游戏开发和AR/VR场景中具有重要应用价值,其中Core Graphics的图形上下文管理和OpenGL ES的

weixin_32288959的博客 233

YOLOV8主干改进方法:C2f-Dual——DualConv轻量化双卷积设计(附改进代码)

DualConv是一种创新的卷积网络结构,旨在构建轻量级的深度神经网络。它通过结合3×3和1×1的卷积核处理相同的输入特征映射通道,优化了信息处理和特征提取。DualConv利用组卷积技术高效排列卷积滤波器,大大降低了计算成本和参数数量。

m0_74890428的博客 4698

ollama如何在自己的服务器上跑Qwen3(小白必看)

在国内下载ollama最新安装包时,使用curl -fsSL https://ollama.com/install.sh | sh命令可能会遇到网络问题导致下载进度停滞。为了解决这一问题,可以通过国内的镜像源进行下载,例如使用modelscope社区提供的最新ollama镜像仓库。具体步骤包括:首先通过pip install modelscope安装modelscope,然后使用modelscope download命令下载ollama-linux镜像,接着进入下载目录并赋予安装脚本执行权限,最后运行安装脚

Ven%的博客 756

iOS绘图与手势识别终极指南:从基础到实战的完整教程

如果你正在寻找一个全面的iOS绘图与手势识别学习资源,那么iOSProject项目绝对是你的理想选择!这个开源项目汇集了丰富的iOS绘图、手势识别、核心动画和物理仿真等实用功能,为iOS开发者提供了一个完整的Objective-C学习宝库。无论是初学者想要快速上手iOS绘图技术,还是有经验的开发者需要参考实际项目实现,iOSProject都能为你提供宝贵的实战经验和代码示例。 ## 📱 项目概

gitblog_00398的博客 414

[VT虚拟化驱动] 定义类及初始化内存区域

文章目录前言框架整体流程图类的定义初始化内存区域本章代码 前言 为什么不用C而用C++呢? 在单核的情况下,用C还比较方便些,但在多核的情况下,每个核心都需要分配有对应的一个VMX区域,VMCS区域,MsrBitmap区域和栈空间,以及对应的初始化函数,如果使用安装DPC回调的方式在多核情况下进行初始化,只使用同一个初始化函数,当函数被多个CPU核心同时执行,会出现很多意想不到的的错误,我用自旋锁试了一下是依照各种错误,所以果断用C++了,把这些每个核心都需要一份的封装到一个类里 框架整体流程图 类的定义

吾无法无天的博客 1835

【Swift图片处理终极指南】:掌握高效图像操作的7大核心技术

掌握Swift图片处理的7大核心技术,解决iOS图像操作常见难题。涵盖滤镜应用、裁剪缩放、性能优化等场景,提升App视觉体验与运行效率。方法实用、适配最新系统,值得收藏。

StepLens的博客 802

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

李洪强经典面试题44

绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation 属性解析:keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到...

weixin_33974433的博客 122

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

CGContext 小记

from http://www.cocoachina.com/bbs/read.php?tid=75122      CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文  CGContextMoveToPoint 开始画线  CGContextAddLineToPoint 画直线    CGContextAddEll

cactusz的博客 211

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: iOS的手势识别器
下一篇: 核心动画——Core Animation
活在生活里
博客等级 码龄11年 94粉丝 82原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值