OC笔记 - Quartz2D(2015.3.22)

1.什么是Quartz2D

Quartz2D是一个二维绘图引擎,同时支持iOS和Mac系统

Quartz2D能完成的工作

绘制图形 : 线条\三角形\矩形\圆\弧等

绘制文字

绘制\生成图片(图像)

读取\生成PDF

截图\裁剪图片

自定义UI控件

… …

 

Quartz2D的API是纯C语言的

Quartz2D的API来自于CoreGraphics框架

数据类型和函数基本都以CG作为前缀

CGContextRef

CGPathRef

CGContextStrokePath(ctx);

……

 

2.图形上下文

图形上下文(GraphicsContext):是一个CGContextRef类型的数据

图形上下文的作用

保存绘图信息、绘图状态

决定绘制的输出目标(绘制到什么地方去?)

(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

相同的一套绘图序列,指定不同的GraphicsContext,就可将相同的图像绘制到不同的目标上

 

Quartz2D提供了以下几种类型的GraphicsContext:

BitmapGraphics Context

PDFGraphics Context

WindowGraphics Context

LayerGraphics Context

PrinterGraphics Context

 

3.自定义view

(1)如何利用Quartz2D自定义view?(自定义UI控件)

(2)如何利用Quartz2D绘制东西到view上?

首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去

其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面

(3)自定义view的步骤

新建一个类,继承自UIView

实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中

(4)取得跟当前view相关联的图形上下文

(5)绘制相应的图形内容

(6)利用图形上下文将绘制的所有内容渲染显示到view上面

 

4.drawRect:

(1)为什么要实现drawRect:方法才能绘图到view上?

因为在drawRect:方法中才能取得跟view相关联的图形上下文

(2)drawRect:方法在什么时候被调用?

当view第一次显示到屏幕上时(被加到UIWindow上显示出来)

调用view的setNeedsDisplay或者setNeedsDisplayInRect:时

 

5.drawRect:中取得的上下文

(1)在drawRect:方法中取得上下文后,就可以绘制东西到view上

(2)View内部有个layer(图层)属性,drawRect:方法中取得的是一个LayerGraphics Context,因此,绘制的东西其实是绘制到view的layer上去了

(3)View之所以能显示东西,完全是因为它内部的layer

 

6.Quartz2D绘图的代码步骤

获得图形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

 

拼接路径(下面代码是搞一条线段)

CGContextMoveToPoint(ctx, 10, 10);

CGContextAddLineToPoint(ctx, 100, 100);

 

绘制路径

CGContextStrokePath(ctx); //CGContextFillPath(ctx);

 

7.常用拼接路径函数

新建一个起点

void CGContextMoveToPoint(CGContextRef c, CGFloatx, CGFloat y)

 

添加新的线段到某个点

void CGContextAddLineToPoint(CGContextRef c, CGFloatx, CGFloat y)

 

添加一个矩形

void CGContextAddRect(CGContextRef c, CGRectrect)

 

添加一个椭圆

void CGContextAddEllipseInRect(CGContextRef context, CGRectrect)

 

添加一个圆弧

void CGContextAddArc(CGContextRef c, CGFloatx, CGFloat y,

  CGFloat radius, CGFloatstartAngle, CGFloat endAngle, int clockwise)

 

8.常用绘制路径函数

Mode参数决定绘制的模式

void CGContextDrawPath(CGContextRef c, CGPathDrawingModemode)

 

绘制空心路径

void CGContextStrokePath(CGContextRef c)

 

绘制实心路径

void CGContextFillPath(CGContextRef c)

 

提示:一般以CGContextDrawCGContextStrokeCGContextFill开头的函数,都是用来绘制路径的

 

9.图形上下文栈的操作

将当前的上下文copy一份,保存到栈顶(那个栈叫做图形上下文栈”)

void CGContextSaveGState(CGContextRef c)

 

将栈顶的上下文出栈,替换掉当前的上下文

void CGContextRestoreGState(CGContextRef c)

 

10.内存管理:对象的所有权

Quartz使用Core Foundation内存管理模型(引用计数)。所以,对象的创建与销毁与通常的方式是一样的。在Quartz中,需要记住如下一些规则:

(1)如果创建或拷贝一个对象,你将拥有它,因此你必须释放它。通常,如果使用含有”Create”或“Copy”单词的函数获取一个对象,当使用完后必须释放,否则将导致内存泄露。

(2)如果使用不含有”Create”或“Copy”单词的函数获取一个对象,你将不会拥有对象的引用,不需要释放它。

(3)如果你不拥有一个对象而打算保持它,则必须retain它并且在不需要时release掉。可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorspace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。同样,可以使用Core Foundation的CFRetain和CFRelease,但是注意不能传递NULL值给这些函数。

 

11.示例代码

/**

 * 图片水印

 */

+ (instancetype)waterImageWithBg:(NSString *)bg logo:(NSString *)logo

{

    UIImage *bgImage = [UIImage imageNamed:bg];

   

    // 1.创建一个基于位图的上下文(开启一个基于位图的上下文)

    UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0);

   

    // 2.画背景

    [bgImagedrawInRect:CGRectMake(0, 0,bgImage.size.width,bgImage.size.height)];

   

    // 3.画右下角的水印

    UIImage *waterImage = [UIImage imageNamed:logo];

    CGFloat scale = 0.2;

    CGFloat margin = 5;

    CGFloat waterW = waterImage.size.width *scale;

    CGFloat waterH = waterImage.size.height *scale;

    CGFloat waterX = bgImage.size.width -waterW - margin;

    CGFloat waterY = bgImage.size.height -waterH - margin;

   [waterImage drawInRect:CGRectMake(waterX, waterY, waterW, waterH)];

   

    // 4.从上下文中取得制作完毕的UIImage对象

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

   

    // 5.结束上下文

    UIGraphicsEndImageContext();

   

    return newImage;

}

 

 

/**

 * 图片裁剪

 */

+ (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor

{

    // 1.加载原图

    UIImage *oldImage = [UIImage imageNamed:name];

   

    // 2.开启上下文

    CGFloat imageW = oldImage.size.width + 2 * borderWidth;

    CGFloat imageH = oldImage.size.height + 2 * borderWidth;

    CGSize imageSize = CGSizeMake(imageW, imageH);

    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);

   

    // 3.取得当前的上下文

    CGContextRef ctx = UIGraphicsGetCurrentContext();

   

    // 4.画边框(大圆)

   [borderColor set];

    CGFloat bigRadius = imageW * 0.5; // 大圆半径

    CGFloat centerX = bigRadius; // 圆心

    CGFloat centerY = bigRadius;

    CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);

    CGContextFillPath(ctx); // 画圆

   

    // 5.小圆

    CGFloat smallRadius = bigRadius - borderWidth;

CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);

// 5.按照当前的路径形状(圆形)裁剪, 超出这个形状以外的内容都不显示

    // 裁剪(后面画的东西才会受裁剪的影响)

    CGContextClip(ctx);

   

    // 6.画图

   [oldImage drawInRect:CGRectMake(borderWidth, borderWidth, oldImage.size.width,oldImage.size.height)];

   

    // 7.取图

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

   

    // 8.结束上下文

    UIGraphicsEndImageContext();

   

    return newImage;

}

 

 

/**

 * 屏幕截图

 */

+ (instancetype)captureWithView:(UIView *)view

{

    // 1.开启上下文

    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);

   

    // 2.将控制器viewlayer渲染到上下文

   [view.layer renderInContext:UIGraphicsGetCurrentContext()];

   

    // 3.取出图片

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

   

    // 4.结束上下文

    UIGraphicsEndImageContext();

   

    return newImage;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用以下命令启动这些 jar 包: ``` nohup java -jar codegen-service.jar > codegen-service.log & nohup java -jar data-market-service-integration.jar > data-market-service-integration.log & nohup java -jar data-market-service-mapping.jar > data-market-service-mapping.log & nohup java -jar data-market-service.jar > data-market-service.log & nohup java -jar data-masterdata-service.jar > data-masterdata-service.log & nohup java -jar data-metadata-service-console.jar > data-metadata-service-console.log & nohup java -jar data-metadata-service.jar > data-metadata-service.log & nohup java -jar data-quality-service.jar > data-quality-service.log & nohup java -jar data-standard-service.jar > data-standard-service.log & nohup java -jar data-visual-service.jar > data-visual-service.log & nohup java -jar datax-auth.jar > datax-auth.log & nohup java -jar datax-config.jar > datax-config.log & nohup java -jar datax-eureka.jar > datax-eureka.log & nohup java -jar datax-gateway.jar > datax-gateway.log & nohup java -jar datax-tool-monitor.jar > datax-tool-monitor.log & nohup java -jar email-service.jar > email-service.log & nohup java -jar file-service.jar > file-service.log & nohup java -jar quartz-service.jar > quartz-service.log & nohup java -jar system-service.jar > system-service.log & nohup java -jar workflow-service.jar > workflow-service.log & ``` 其中,`nohup` 命令可以使程序在后台运行,并将输出重定向到日志文件中。`&` 符号表示在后台运行该命令。请确保在执行此命令之前,已经安装了 Java 运行时环境,并且当前路径下存在相应的 jar 文件。如果 jar 文件不在当前路径下,可以使用绝对路径或相对路径指定文件的位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值