• IOS画图


    首先说明一下要求,知道了要求之后才能更好地工作呢。

    1、通过滑动滑块来修改画笔的粗细;最小值为4,最大值为15;UISlider;

    2、点击撤销按钮后,绘图区域撤销上一次画线操作;

    3、点击保存按钮后,将绘图区域的图片按照顺序保存到上方的视图中;UIImageView;

    4、保存的图片大于6张后,继续从第一个视图按照顺序往下保存;

    5、每次点击按钮后,还要将绘制的图片保存到iOS相册内; 可以通过UIImageWriteToPhotosAlbum函数保存到图片相册,保存成功后可以在iPhone模拟器的照片应用程序中查看

     

    首先创建工程,single view Application

    先说说思路:

    1.将界面给布置好,图片1——6的位置为UIImageView,"撤销"“保存",是两个UIButton,中间是一个UISlider,下面绘图区是一个UIView

    2.当点击保存的时候,会弹出对话框,提示是否进行保存,如果保存就将绘图区的图片保存到上面同时保存的本地的照片库中,如果点击取消,则不进行保存

    3.写保存,撤销按钮点击事件,(NSLog(@"hello");)进行界面测试

    4.对绘图区进行书写,进行绘图。

    5.绘图区应该是在外面是一个自己创建的继承与UIView的View

    6.在绘图区的操作:

      6.1.重写

      - (void)drawRect:(CGRect)rect;方法

      首先是重写父视图的drawRect:rect方法;

      6.2.添加

      - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;方法

      6.3.添加

      - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;方法

      6.4.将每一次画得图保存为一个image,添加方法

      - (UIImage *)getImageFromCurrentContext;即得到当前视图的截图

      6.5.

    画图过程应该是:每一次触摸屏幕的开始,就是一个触摸路径的开始,然后开始绘制,在绘制的过程中,只要绘制就会调用touchesMoved:方法

    ,同时对图片进行调用[self setNeedsDisplayInrect:rect];程序就会跳转到drawRect:方法中,对图片进行绘制。

    根据上面的思路,来进行工作的实施。

    首先是界面:

    在viewController.m 文件中书写代码:

    #import "ViewController.h"
    #import "CustomView.h"
    #import "CustomManager.h"
    #import "CustomPath.h"
    
    @interface ViewController ()
    {
        NSInteger  imageCount;
    }
    @end
    
    @implementation ViewController
    #pragma mark---------------------------------------viewDidLoad
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    //后面的白板容器视图
        imageCount = 0;
    	UIView * containerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
        containerView.backgroundColor = [UIColor whiteColor];
        containerView.tag = 0;
        [self.view addSubview:containerView];
    //上面的文字视图
        UIView * titleView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 64)];
        [containerView addSubview:titleView];
    //保存和撤销按钮
        UIButton * cancelButton = [[UIButton alloc]initWithFrame:CGRectMake(10, 0, 50, 40)];
        [cancelButton setTitle:@"撤销" forState:UIControlStateNormal];
        [cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [cancelButton addTarget:self action:@selector(didClickCancelButton:) forControlEvents:UIControlEventTouchUpInside];
        cancelButton.backgroundColor = [UIColor grayColor];
        
        UIButton * saveButton = [[UIButton alloc]initWithFrame:CGRectMake(260, 0, 50, 40)];
        [saveButton setTitle:@"保存" forState:UIControlStateNormal];
        [saveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [saveButton addTarget:self action:@selector(didClickSaveButton:) forControlEvents:UIControlEventTouchUpInside];
        saveButton.backgroundColor = [UIColor grayColor];
        
        [containerView addSubview:cancelButton];
        [containerView addSubview:saveButton];
    //添加划线空间
        UISlider * slider = [[UISlider alloc]initWithFrame:CGRectMake(70, 0, 150, 0)];
        [titleView addSubview:slider];
        slider.minimumValue = 4.0f;
        slider.maximumValue = 15.0f;
        [slider addTarget:self action:@selector(changeSliderValue:) forControlEvents:UIControlEventValueChanged];
        
        
    //添加6个UIImageView
        UIView * sixContainerView = [[UIView alloc]initWithFrame:CGRectMake(0, 50, 320, 215)];
        sixContainerView.backgroundColor = [UIColor greenColor];
        sixContainerView.tag = 3;
        [containerView addSubview:sixContainerView];
        
        UIImageView * firstImage = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 100, 100)];
        UIImageView * secondImage = [[UIImageView alloc]initWithFrame:CGRectMake(110, 5, 100, 100)];
        UIImageView * thirdImage = [[UIImageView alloc]initWithFrame:CGRectMake(215, 5, 100, 100)];
        UIImageView * forthImage = [[UIImageView alloc]initWithFrame:CGRectMake(5, 110, 100, 100)];
        UIImageView * fifthImage = [[UIImageView alloc]initWithFrame:CGRectMake(110, 110, 100, 100)];
        UIImageView * sixthImage = [[UIImageView alloc]initWithFrame:CGRectMake(215, 110, 100, 100)];
    
        firstImage.backgroundColor = [UIColor grayColor];
        secondImage.backgroundColor = [UIColor grayColor];
        [thirdImage setBackgroundColor:[UIColor grayColor]];
        forthImage.backgroundColor = [UIColor grayColor];
        fifthImage.backgroundColor = [UIColor grayColor];
        sixthImage.backgroundColor = [UIColor grayColor];
        firstImage.tag = 1001;
        secondImage.tag = 1002;
        thirdImage .tag = 1003;
        forthImage.tag = 1004;
        fifthImage .tag = 1005;
        sixthImage.tag = 1006;
        firstImage.userInteractionEnabled = YES;
        secondImage.userInteractionEnabled = YES;
        thirdImage.userInteractionEnabled = YES;
        forthImage.userInteractionEnabled = YES;
        fifthImage.userInteractionEnabled = YES;
        sixthImage.userInteractionEnabled = YES;
        [firstImage clearsContextBeforeDrawing];
        [sixContainerView addSubview:firstImage];
        [sixContainerView addSubview:secondImage];
        [sixContainerView addSubview:thirdImage];
        [sixContainerView addSubview:forthImage];
        [sixContainerView addSubview:fifthImage];
        [sixContainerView addSubview: sixthImage];
        
    //添加颜色选择
        UIButton * redButton = [[UIButton alloc]initWithFrame:CGRectMake(30, 270, 25, 10)];
        redButton.backgroundColor = [UIColor redColor];
        [redButton addTarget:self action:@selector(didClickRedButton:) forControlEvents:UIControlEventTouchUpInside];
        UIButton * greenButton = [[UIButton alloc]initWithFrame:CGRectMake(150, 270, 25, 10)];
        [greenButton setBackgroundColor:[UIColor greenColor]];
        [greenButton addTarget:self action:@selector(didClickGreenButton:) forControlEvents:UIControlEventTouchUpInside];
        UIButton * blueButton = [[UIButton alloc]initWithFrame:CGRectMake(260, 270, 25, 10)];
        blueButton.backgroundColor = [UIColor blueColor];
        [blueButton addTarget:self action:@selector(didClickBlueButton:) forControlEvents:UIControlEventTouchUpInside];
        
        [containerView addSubview:redButton];
        [containerView addSubview:greenButton];
        [containerView addSubview:blueButton];
    //添加画板视图
        CustomView * cView = [[CustomView alloc]initWithFrame:CGRectMake(5, 280, 310, 210)];
        cView.backgroundColor= [UIColor grayColor];
        cView.tag = 1;
        [containerView addSubview:cView];
    }
    

      当点击保存按钮和撤销按钮,进行相应地事件的触发,当跳出一个提示框后进行的操作:

    #pragma mark---------------------------------------alertView
    - (void)alertView:(UIAlertView *)alertViewt clickedButtonAtIndex:(NSInteger)buttonIndex
    
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *) [containerView viewWithTag:1];
        
        NSMutableArray * pathListArray =  [CustomManager defaultManager].pathList;
        UIView * sixContainerView = [containerView viewWithTag:3];
        NSArray * array = [sixContainerView subviews];
        UIImage * tempImage = [cView getImageFromCurrentContext];
        
        switch (buttonIndex) {
            case 0:
            {
                [pathListArray removeAllObjects];
                [cView setNeedsDisplay];
            }
                NSLog(@"取消");
                break;
            case 1:
            {
                UIImageWriteToSavedPhotosAlbum(tempImage, NULL, NULL, NULL);
                imageCount++;
                switch (imageCount) {
                    case 1:
                        ((UIImageView *)array[0]).image = tempImage;
                        break;
                    case 2:
                        ((UIImageView *)array[1]).image = tempImage;
                        break;
                    case 3:
                        ((UIImageView *)array[2]).image = tempImage;
                        break;
                    case 4:
                        ((UIImageView *)array[3]).image = tempImage;
                        break;
                    case 5:
                        ((UIImageView *)array[4]).image = tempImage;
                        break;
                    case 6:
                        ((UIImageView *)array[5]).image = tempImage;
                        break;
                    default:
                        break;
                }
                [pathListArray removeAllObjects];
                [cView setNeedsDisplay];
            }
                NSLog(@"确定");
                break;
        }
    }
    
    
    #pragma mark---------------------------------------changeSliderValue:
    - (void) changeSliderValue:(UISlider *)sender
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *)[containerView viewWithTag:1];
        cView.lineWidth = sender.value;
        NSLog(@"%f",sender.value);
    }
    #pragma mark---------------------------------------didClickSaveButton:
    - (void) didClickSaveButton:(UIButton *)sender
    {
        if (imageCount > 5) {
            imageCount = 0;
        }
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"是否保存" message:@"要保存吗?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alert show];
        
        NSLog(@"save click");
        
    }
    
    
    
    #pragma mark---------------------------------------didClickCancelButton:
    - (void) didClickCancelButton:(UIButton *)sender
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *) [containerView viewWithTag:1];
        
        NSMutableArray * pathListArray =  [CustomManager defaultManager].pathList;
        [pathListArray removeLastObject];
        [cView setNeedsDisplay];
     
        NSLog(@"cancel click");
    }
    
    #pragma mark---------------------------------------didClickBlueButton:
    - (void) didClickBlueButton:(UIButton *)sender
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *) [containerView viewWithTag:1];
        cView.lineColor = [UIColor blueColor];
        
        
        NSLog(@"blue");
    }
    #pragma mark---------------------------------------didClickRedButton:
    - (void) didClickRedButton:(UIButton *)sender
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *) [containerView viewWithTag:1];
        cView.lineColor = [UIColor redColor];
        NSLog(@"red");
    }
    #pragma mark---------------------------------------didClickGreenButton:
    - (void) didClickGreenButton:(UIButton *)sender
    {
        UIView * containerView = [self.view viewWithTag:0];
        CustomView * cView = (CustomView *) [containerView viewWithTag:1];
        cView.lineColor = [UIColor greenColor];
        NSLog(@"green");
    }
    #pragma mark---------------------------------------didReceiveMemoryWarning
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }
    @end 

    创建一个单例:用来存储每一条路径的信息。一个数组。这个数组中得元素是一个另外一个类的每一个对象,另外一个类是linpath类。

    在这个类中保存着每一个对象的所有数据,(线的路径,线的宽度,线的颜色)。

    然后再drawRect:方法中for (in)这个单例中那个数组的所有元素,遍历出后,进行绘画和渲染。

     在这里,我们分别实现各个方法,

    首先创建一个CustomView,用来进行绘图:绘图代码:

    首先是CustomView.h文件中得声明:

    #import <UIKit/UIKit.h>
    
    @interface CustomView : UIView
    @property (nonatomic,retain) UIColor* lineColor;
    - (CGMutablePathRef) pathFromPoint:(CGPoint)originPoint toPoint:(CGPoint) finalPoint;
    - (UIImage *)getImageFromCurrentContext;
    
    @property (nonatomic,assign)float lineWidth;
    @end
    

      然后是CustomView.m文件中各个方法的实现。

    #import "CustomView.h"
    #import "CustomManager.h"
    #import "CustomPath.h"
    //添加自定义视图的延展...
    @interface CustomView ()
    
    //获取坐标内的路径...
    //- (CGMutablePathRef) pathFromPoint:(CGPoint)originPoint toPoint:(CGPoint) finalPoint;
    //- (UIImage *)getImageFromCurrentContext;
    @end
    //静态内联函数
    //程序启动后,这种类型的函数就已经准备完毕,在代码区准备程序内调用
    static inline CGPoint midPoint(CGPoint point1,CGPoint point2)
    {
        CGFloat minX = (point1.x + point2.x)/2.0f;
        CGFloat minY = (point2.y + point2.y)/2.0f;
        return CGPointMake(minX, minY);
    }
    @implementation CustomView
    {
        //添加私有地实例变量
        //启动点...
        CGPoint startPoint;
        //结束点...
        CGPoint endPoint;
        //控制点
        CGPoint controlPoint;
        UIImage *tempImage;
        
        //声明路径私有地中间变量
        CGMutablePathRef tempPath;
        
        //声明每一次触摸完成后的路径
        CGMutablePathRef touchPath;
        
        //声明全部路径变量,用来存储所有的中间路径.....
        CGMutablePathRef totalPath;
        
        
    }
    #pragma mark---------------------------------------初始化
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            
            startPoint = CGPointZero;
            endPoint = CGPointZero;
            controlPoint = CGPointZero;
            //创建全部路径对象存储空间
    //        totalPath = CGPathCreateMutable();
            _lineColor = [UIColor whiteColor];
        }
        return self;
    }
    #pragma mark---------------------------------------开始画 drawRect:
    
    - (void)drawRect:(CGRect)rect
    {
        //通知父类,开始画图....
       [super drawRect:rect];
        
        //如果两个都是(0,0),则不画图...
        if (CGPointEqualToPoint(startPoint, CGPointZero) && CGPointEqualToPoint(endPoint,CGPointZero)) {
            return;
        }
        
        //1.获取当前画布...
        CGContextRef context = UIGraphicsGetCurrentContext();//context 就是传过来的rect
        NSMutableArray * pathListArray =  [CustomManager defaultManager].pathList;
        
        for (CustomPath * itemPath in pathListArray) {
            
            CGContextSetLineCap(context, kCGLineCapRound);
            CGContextSetLineWidth(context, itemPath.lineWidth);
            
            CGContextSetStrokeColorWithColor(context, itemPath.lineColor);
            
            CGContextAddPath(context, itemPath.linePath);
            
            CGContextStrokePath(context);
            
        }
        
        
        /**/
        //1.开始创建图片画布
    
        /**/
        
        
        
        
    }
    
    #pragma mark---------------------------------------touchBegan
    - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        //每一次触摸屏幕的开始,就是一个触摸路径的开始.....
        touchPath = CGPathCreateMutable();
        CustomPath * itemPath = [[CustomPath alloc]init];
        itemPath.lineWidth =_lineWidth;
        itemPath .lineColor = _lineColor.CGColor;
        itemPath.linePath = touchPath;
        [[CustomManager defaultManager].pathList addObject:itemPath];
        //获取触摸对象
        UITouch * touch = [touches anyObject];
        //设置每次触摸的点
        startPoint = [touch previousLocationInView:self];
        endPoint = [touch previousLocationInView:self];
        controlPoint =[touch previousLocationInView:self];
        [self touchesMoved:touches withEvent:event];
    }
    #pragma mark---------------------------------------touchesMoved
    //当手指开始触摸得时候,实现的方法...
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        //获取当前的触摸对象
        UITouch * touch = [touches anyObject];
        //设置起点
        startPoint = controlPoint;
        //设置控制点为前一个触摸点
        controlPoint = [touch previousLocationInView:self];
        //设置中点为当前触摸点
        endPoint = [touch locationInView:self];
        
        //生成截图图片对象...
    //    tempImage = [self getImageFromCurrentContext];
        
        CGPoint mid1 = midPoint(startPoint,controlPoint);
        CGPoint mid2 = midPoint(controlPoint, endPoint);
        //获取当前应该绘制的路径
        tempPath = [self pathFromPoint:mid1 toPoint:mid2];
        //获取最小的能够容纳路径的矩形体积
        CGRect rect = CGPathGetBoundingBox(tempPath);
        rect.origin.x -=15.0f;
        rect.origin.y -=15.0f;
        rect.size.height +=30.0f;
        rect.size.width +=30.0f;
        
        //将中间变量tempPath添加到全部路径
    //    CGPathAddPath(totalPath, NULL, tempPath);
        //将中间变量tempPath添加到每一个的触摸路径touchPath内
        CGPathAddPath(touchPath, NULL, tempPath);
        //修改最后的自定义的path对象
        CustomPath * itemPath = [[CustomManager defaultManager].pathList lastObject];
        itemPath.linePath = touchPath;
        
        //这里的self是实例对象
        [self setNeedsDisplayInRect:rect];
    }
    #pragma mark---------------------------------------touchesEnded
    //当手指结束触摸时,触发的方法
    - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        CustomPath * itemPath = [[CustomPath alloc]init];
        itemPath.linePath = touchPath;
    }
    
    //获取当前视图的截图....
    #pragma mark---------------------------------------画图
    
    - (UIImage *)getImageFromCurrentContext
    {
        //1.开始创建图片画布
        UIGraphicsBeginImageContext(self.bounds.size);
        //2.将视图的内容渲染到图片画布上
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        //3.通过图片画布获取当前画布...
        UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
        //4.结束图片画布
        UIGraphicsEndImageContext();
        return result;
    }
    
    
    #pragma mark---------------------------------------获取坐标内路径
    //获取坐标内的路径...
    - (CGMutablePathRef) pathFromPoint:(CGPoint)originPoint toPoint:(CGPoint) finalPoint
    {
        //创建块
        CGMutablePathRef path = CGPathCreateMutable();
        //移动到出发点
        CGPathMoveToPoint(path, NULL, originPoint.x, originPoint.y);
        //添加直线结束点
    //    CGPathAddLineToPoint(path,NULL , finalPoint.x, finalPoint.y);
        
        
        //添加曲线,通过控制点,到结束点
        CGPathAddQuadCurveToPoint(path, NULL, controlPoint.x, controlPoint.y, finalPoint.x, finalPoint.y);
    
        
        //CGPathRef,CGContextRef,CGColorRef
        //的基本类型都是CFtypeRef类型的
        //而ARC不支持此类型的自动释放
        
        //将cgpathref对象添加到自动释放池
        CFAutorelease(path);
        //将路径返回
        return path ;
    }
    
    
    @end
    

      

    附件:

    该程序的例子:

    文件存到网盘了。百度网盘。

  • 相关阅读:
    序列化 Serialization
    http soap关系
    sql 查询
    返回最后插入到标识列的值(scope_identity.ident_current.@@identity)
    匿名方法
    九、volatile与Java内存模型
    八、Java内存模型JMM
    十、CAS
    CUSTOM ROUTE CONSTRAINTS
    获取本地数据库
  • 原文地址:https://www.cnblogs.com/yinyakun/p/3428309.html
Copyright © 2020-2023  润新知