涂鸦

    

Main.storyboard

下面四个颜色设置在右边的view中background

ViewController.m

//

//  ViewController.m

//  6A06.涂鸦

//

//  Created by huan on 16/1/30.

//  Copyright © 2016 huanxi. All rights reserved.

//

 

#import "ViewController.h"

#import "CZPaintView.h"

#import "UIImage+CZ.h"

@interface ViewController ()

 

@property (weak, nonatomic) IBOutlet CZPaintView *paintView;//画板

 

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    

    //1.拖一个view,用于画板

    //2.监听触摸的事件,记录触摸的点

    //3.根据触摸的点进行绘制

    

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

-(IBAction)back:(id)sender

{

    [self.paintView back];

    

    //1. 数组里 最后一条线删除

    

    //2. 重绘

    

}

 

-(IBAction)clean:(id)sender{

    [self.paintView clear];

}

 

-(IBAction)save:(id)sender{

    //将画板 保存成一张图片

    UIImage *captureImage = [UIImage captureImage:self.paintView];

    NSData *imgData = UIImagePNGRepresentation(captureImage);

    [imgData writeToFile:@"/Users/huan/Desktop/capture.png" atomically:YES];

}

 

-(IBAction)colorBtnClick:(UIButton *)sender{

    //设置paintView当前颜色

    self.paintView.currentColor = sender.backgroundColor;

    NSLog(@"%s",__func__);

}

@end

CZPaintView.h

#import <UIKit/UIKit.h>

 

@interface CZPaintView : UIView

 

@property (nonatomic, strong) UIColor *currentColor;//当前选中的颜色

 

-(void)back;

-(void)clear;

 

 

@end

CZPaintView.m

//

//  CZPaintView.m

//  6A06.涂鸦

//

//  Created by huan on 16/1/30.

//  Copyright © 2016 huanxi. All rights reserved.

//

 

#import "CZPaintView.h"

@interface CZPaintView()

/**

 * 存储所有线的点,数组里面存一条线的数组

 */

@property (nonatomic, strong) NSMutableArray *pointOfAllLine;

@property (nonatomic, strong) NSMutableArray *pointOfLine;//一条线上的所有点

/**

 * 存储线的颜色 每一条对应里面一个元素

 */

@property (nonatomic, strong) NSMutableArray *colorsOfAllLine;

@end

@implementation CZPaintView

 

-(NSMutableArray *)colorsOfAllLine{

    if (!_colorsOfAllLine) {

        _colorsOfAllLine = [NSMutableArray array];

    }

    return _colorsOfAllLine;

}

 

-(NSMutableArray *)pointOfAllLine{

    if (!_pointOfAllLine) {

        _pointOfAllLine = [NSMutableArray array];

    }

    return _pointOfAllLine;

}

//-(NSMutableArray *)pointOfLine{

//    if (!_pointOfLine) {

//        _pointOfLine = [NSMutableArray array];

//    }

//    return _pointOfLine;

//}

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

 */

- (void)drawRect:(CGRect)rect {

    // Drawing code

    //上下文

    CGContextRef layerContext = UIGraphicsGetCurrentContext();

    //设置线宽

    CGContextSetLineWidth(layerContext, 3);

    

    //设置首尾和接点的样式

    CGContextSetLineCap(layerContext, kCGLineCapRound);

    CGContextSetLineJoin(layerContext, kCGLineJoinRound);

    //遍历点进行绘制

//    NSInteger count = self.pointOfLine.count;

//    for (NSInteger i = 0; i < count; i ++) {

//        //获取点

//        CGPoint position = [self.pointOfLine[i] CGPointValue];

//        

//        if (i == 0) {

//            CGContextMoveToPoint(layerContext, position.x, position.y);

//        }else{

//                CGContextAddLineToPoint(layerContext, position.x, position.y);

//            }

//        }

//        //渲染

//        CGContextStrokePath(layerContext);

    

    //遍历多少条线

    NSInteger lineCount = self.pointOfAllLine.count;

    for (NSInteger i = 0; i < lineCount; i ++) {

        //取出当前一条线的数组

        NSArray *pointOfAline = self.pointOfAllLine[i];

        

        //设置颜色

        UIColor *lineColor = self.colorsOfAllLine[i];

        [lineColor set];

        //画线

        //取出"线"的个数进行绘制

        NSInteger pointsCount = pointOfAline.count;

        for (NSInteger j = 0; j < pointsCount; j++) {

            CGPoint point = [pointOfAline[j] CGPointValue];

            if (j == 0) {

                CGContextMoveToPoint(layerContext, point.x, point.y);

            }else{

                CGContextAddLineToPoint(layerContext, point.x, point.y);

            }

            }

        //渲染

        CGContextStrokePath(layerContext);

        

    }

    

    

    

}

 

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    //创建一个数组,存放当前一条线的点

    NSMutableArray *pointsOfAlline = [NSMutableArray array];

    

    //添加到pointsOfAllLine

    [self.pointOfAllLine addObject:pointsOfAlline];

    

    //保存当前一条线的颜色

    if (!self.currentColor) {//为空,给个默认的黑色

        [self.colorsOfAllLine addObject:[UIColor blackColor]];

    }else{

        [self.colorsOfAllLine addObject:self.currentColor];

    }

    

}

 

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    // 2.监听触摸的事件,记录触摸的点

    //2.0 给一个属性 保存所有线的点

    

    //获取当前的位置

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:touch.view];

    

    //2.1 获取当前一条线数组 添加

    NSMutableArray *pointsOfAline = [self.pointOfAllLine lastObject];

    [pointsOfAline addObject:[NSValue valueWithCGPoint:touchPoint]];

    

//    [self.pointOfLine addObject:[NSValue valueWithCGPoint:touchPoint]];

    //3.根据触摸的点进行绘制

    [self setNeedsDisplay];

}

 

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    NSLog(@"多少条线 %ld", self.pointOfAllLine.count);

}

 

-(void)back{

    //1. 数组里 最后一条线删除

    [self.pointOfAllLine removeLastObject];

    //2. 重绘

    [self setNeedsDisplay];

}

 

-(void)clear{

    //1. 数组里 所有的线删除

    [self.pointOfAllLine removeAllObjects];

    //2. 重绘

    [self setNeedsDisplay];

}

@end

UIImage + CZ.h

//

//  UIImage+CZ.h

//  B06.图片水印

//

//  Created by Apple on 15/1/2.

//  Copyright (c) 2015 itcast. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

@interface UIImage (CZ)

 

/**

 *

 *  @param bgImageName    背景图片

 *  @param waterImageName 水印图片

 *  @param scale 图片生成的比例

 *  @return 添加了水印的背景图片

 */

+(UIImage *)waterImageWithBgImageName:(NSString *)bgImageName waterImageName:(NSString *)waterImageName scale:(CGFloat)scale;

 

 

/**

 *

 *  @param imageName    需要裁剪的图片

 *  @param borderColor 边框的颜色

 *  @param borderWidth 边框的宽度

 *  @return 一个裁剪 带有边框的圆形图片

 */

+(UIImage *)circleImageWithImageName:(NSString *)imageName borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;

 

/**

 *  @param captureView 需要裁图View

 *  @return 返回view的图片

 */

+(UIImage *)captureImage:(UIView *)captureView;

 

@end

//

//  UIImage+CZ.m

//  B06.图片水印

//

//  Created by Apple on 15/1/2.

//  Copyright (c) 2015 itcast. All rights reserved.

//

 

#import "UIImage+CZ.h"

 

@implementation UIImage (CZ)

 

+(UIImage *)waterImageWithBgImageName:(NSString *)bgImageName waterImageName:(NSString *)waterImageName scale:(CGFloat)scale{

    // 生成一张有水印的图片,一定要获取UIImage对象 然后显示在imageView

    

    //创建一背景图片

    UIImage *bgImage = [UIImage imageNamed:bgImageName];

    //NSLog(@"bgImage Size: %@",NSStringFromCGSize(bgImage.size));

    // 1.创建一个位图【图片】,开启位图上下文

    // size:位图大小

    // opaque: alpha通道 YES:不透明/ NO透明 使用NO,生成的更清析

    // scale 比例 设置0.0为屏幕的比例

    // scale 是用于获取生成图片大小 比如位图大小:20X20 / 生成一张图片:(20 *scale X 20 *scale)

    //NSLog(@"当前屏幕的比例 %f",[UIScreen mainScreen].scale);

    UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, scale);

    

    // 2.画背景图

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

    

    // 3.画水印

    // 算水印的位置和大小

    // 一般会通过一个比例来缩小水印图片

    UIImage *waterImage = [UIImage imageNamed:waterImageName];

#warning 水印的比例,根据需求而定

    CGFloat waterScale = 0.4;

    CGFloat waterW = waterImage.size.width * waterScale;

    CGFloat waterH = waterImage.size.height * waterScale;

    CGFloat waterX = bgImage.size.width - waterW;

    CGFloat waterY = bgImage.size.height - waterH;

    

    

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

    

    // 4.从位图上下文获取 当前编辑的图片

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    

    

    // 5.结束当前位置编辑

    UIGraphicsEndImageContext();

    

    

    return newImage;

}

 

 

+(UIImage *)circleImageWithImageName:(NSString *)imageName borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth{

 

    //需求:从位图上下文,裁剪图片[裁剪成圆形,也添加圆形的边框],生成一张图片

    

    // 获取要裁剪的图片

    UIImage *img = [UIImage imageNamed:imageName];

    CGRect imgRect = CGRectMake(0, 0, img.size.width, img.size.height);

    

    // 1.开启位图上下文

    UIGraphicsBeginImageContextWithOptions(img.size, NO, 0.0);

    

#warning 在自定义的viewdrawRect方法里,调用UIGraphicsGetCurrentContext获取的上下文,是图层上下文(Layer Graphics Context)

    // 1.1 获取位图上下文

    CGContextRef bitmapContext = UIGraphicsGetCurrentContext();

    

    // 2.往位图上下裁剪图片

    

    // 2.1 指定一个圆形的路径,把圆形之外的剪切掉

    CGContextAddEllipseInRect(bitmapContext, imgRect);

    CGContextClip(bitmapContext);

    

    

    // 2.2 添加图片

    [img drawInRect:imgRect];

    

    // 2.3 添加边框

    // 设置边框的宽度

    CGContextSetLineWidth(bitmapContext, borderWidth);

    // 设置边框的颜色

    [borderColor set];

    CGContextAddEllipseInRect(bitmapContext, imgRect);

    CGContextStrokePath(bitmapContext);

    

    

    // 3.获取当前位图上下文的图片

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    

    // 4.结束位图编辑

    UIGraphicsEndImageContext();

    

    return newImage;

}

 

+(UIImage *)captureImage:(UIView *)captureView{

    //创建一个位图上下文

    UIGraphicsBeginImageContext(captureView.bounds.size);

    //view渲染到位图上下文

    [captureView.layer renderInContext:UIGraphicsGetCurrentContext()];

    //获取图片

    UIImage *captureImg = UIGraphicsGetImageFromCurrentImageContext();

    //结束位图的编辑

    UIGraphicsEndImageContext();

    //返回

    return captureImg;

}

 

@end

 如果使用 UIBezierPath 

不需要使用到上下文,内部实现(只有CZPaintView.m与上不同,其他相同)

 // 1.拖一个view,用于画板

 // 2.监听触摸的事件,记录触摸的点

  // 3.根据触摸的点进行绘制

//

//  CZPaintView.m

//  A05.涂鸦

//

//  Created by apple on 15-1-2.

//  Copyright (c) 2015 apple. All rights reserved.

//

 

#import "CZPaintView.h"

 

@interface CZPaintView()

/**

 * 存放所有线的路径数组

 */

 

@property (nonatomic, strong) NSMutableArray *linesPath;

 

@end

 

@implementation CZPaintView

 

-(NSMutableArray *)linesPath{

    if (!_linesPath) {

        _linesPath = [NSMutableArray array];

    }

    return _linesPath;

}

/**实现方法:使用UIBezierPath

 一条线 就使用一个 UIBezierPath对象

 *0. 需要一个数组 存放UIBerzierPath 对象

 *1. 监听move方法

 *2. move方法里获取当前添加到UIBezierPath对象

 *3. 渲染

 */

 

 

 

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

    // Drawing code

#warning UIBezierPath 不需要使用到上下文,内部实现

    //遍历所有path对象

    NSInteger pathCount = self.linesPath.count;

    for (NSInteger i = 0; i < pathCount; i++) {

        //path对象

        UIBezierPath *path = self.linesPath[i];

        

        //设置线宽、首尾样式、连接样式

        path.lineWidth = 3;

        path.lineCapStyle = kCGLineCapRound;

        path.lineJoinStyle = kCGLineJoinRound;

        //

        [path stroke];

    }

}

 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

    //1.获取当前的点

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:touch.view];

    //创建一个 UIBezierPath对象,添加到数组

    UIBezierPath *linePath = [UIBezierPath bezierPath];

    [self.linesPath addObject:linePath];

    //设置path 起始点

    [linePath moveToPoint:touchPoint];

    [self.linesPath addObject:linePath];

    

}

 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

 

    

    //1.获取当前的点

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:touch.view];

    //2.添加当前的到当前的线的路径

    UIBezierPath *currentLinepath = [self.linesPath lastObject];

    

    [currentLinepath addLineToPoint:touchPoint];

    

    //3.渲染

    [self setNeedsDisplay];

    

}

 

 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    

}

 

-(void)back{

    

    

}

 

-(void)clear{

    

    // 1. 数组里 "所有线" 删除

   

}

 

 

@end

原文地址:https://www.cnblogs.com/Lu2015-10-03/p/5178381.html