iOS开发之CG绘图(Core Graphics)

Core Graphics

Core Graphics是一个基于C的绘图专用的API族,它经常被称为QuartZ或QuartZ 2D,是一个二维绘图引擎,同时支持iOS和Mac系统。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变。
QuartZ 2D在开发中比较常用的是截屏/裁剪/自定义UI控件,QuartZ 2D能完成的工作如下:
(1).绘制图形: 线条\三角形\矩形\圆\弧等
(2).绘制文字
(3).绘制\生成图片(图像)
(4).读取\生成PDF
(5).截图\裁剪图片
(6).自定义UI控件
讲到CG绘图,这里有一个很核心的东西:图像上下文CGContextRef, 在UIView中,系统会默认创建一个Layer Graphics Context,它对应UIView的layer属性,该图形上下文可以在drawRect:方法中获取,让我们看下图apple给的官方解释:


CGContextRef.png

英文叽里呱啦说了一大堆,简而言之,换成人话就是CGContextRef就相当于画图用的画板,所有的操作都是在这上面进行的,QuartZ 2D是在这个画布上进行绘制的,在此基础上可以绘制图形: 线条\三角形\矩形\圆\弧等等自定义控件,废话不多说,了解了基本原理以后就是熟悉API了:


CGContext.png

我们来简单的写一个小效果:
- (void)drawRect:(CGRect)rect {
    CGFloat itemW = (rect.size.width - 18)/ 10;
    CGContextRef ref = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(ref, 2.0);
    CGContextSetRGBStrokeColor(ref, 106/255.0, 106/255.0, 106/255.0, 1.0);
    for (int i = 0; i < 9; i ++) {
        //竖线
        CGContextMoveToPoint(ref, itemW * (i +1) +(i * 2) , 0);
        CGContextAddLineToPoint(ref, itemW * (i +1) +(i * 2), rect.size.height);
        //横线
        CGContextMoveToPoint(ref, 0 , itemW * (i +1) +(i * 2));
        CGContextAddLineToPoint(ref, rect.size.width,itemW * (i +1) +(i * 2));
    }
    
    //对角线
    CGContextMoveToPoint(ref, 0, 0);
    CGContextAddLineToPoint(ref, rect.size.width, rect.size.height);
    
    CGContextMoveToPoint(ref, 0, rect.size.height);
    CGContextAddLineToPoint(ref, rect.size.width, 0);
    
    CGContextStrokePath(ref);
}

效果如下


CGContextdemo.png

从代码可以看到CG绘图的步骤如下:
(1)获取当前控件的图形上下文
(2)描述绘画内容
a. 创建图形路径
b. 创建图形起始点
c. 添加图形的终点
(3)把绘画内容添加到图形上下文
(4)设置图形上下文的状态(线宽、颜色等)
(5)渲染图形上下文
当然了,我们这里只是简单的实现了一下,画矩形扇形圆等等的操作,在API里都有,这里简单实现下截屏、水印、裁剪:

水印

// 给图片添加水印
- (UIImage *)addContentToImage:(UIImage *)image contentStr:(NSString *)contentStr {
    if (!_watermarkImage) {
        CGSize size= CGSizeMake(image.size.width, image.size.height); // 画布大小
        UIGraphicsBeginImageContextWithOptions (size, YES, [UIScreen mainScreen].scale);
        [image drawAtPoint:CGPointMake(0, 0)];
        // 获得一个位图图形上下文
        CGContextRef context= UIGraphicsGetCurrentContext();
        CGContextDrawPath(context, kCGPathEOFillStroke);
        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
        paragraph.alignment = NSTextAlignmentCenter;
        NSDictionary *dic = @{ NSFontAttributeName : [UIFont systemFontOfSize:15*image.size.width/kScreenWidth],
                               NSForegroundColorAttributeName : UIColorHex_Alpha(0xffffff, 1),
                               NSParagraphStyleAttributeName : paragraph
                               };
        [contentStr drawInRect:CGRectMake(0, image.size.height - 30*image.size.width/kScreenWidth, image.size.width, 30*image.size.width/kScreenWidth) withAttributes:dic];
        // 返回绘制的新图形
        _watermarkImage = UIGraphicsGetImageFromCurrentImageContext ();
        UIGraphicsEndImageContext();
    }
    DLog(@"width:%lf,height:%lf", _watermarkImage.size.width, _watermarkImage.size.height);
    return _watermarkImage;//获得添加水印后的图片
}

截屏

    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [self.view.layer renderInContext:ctx];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData *data = UIImageJPEGRepresentation(image,1);
    [data writeToFile:kImagePath atomically:YES];

裁剪

    UIGraphicsBeginImageContextWithOptions(oldImage.size, NO, 0);
    //裁剪区域
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    [path addClip];
    [image drawAtPoint:CGPointZero];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

你可能感兴趣的:(iOS开发之CG绘图(Core Graphics))