zoukankan      html  css  js  c++  java
  • ios 实现带矩形框的屏幕截图

    前言:本来只是想实现一个简单的截图功能的,后来又想做的更好一点,就加上了虚线框。要实现截图本身是很容易的,只需要CGImageCreateWithImageInRect:这一个方法即可。后来加了虚线框就复杂了很多,因为还要让虚线框适时的消失。

    现附上最终实现的效果:

    截图后,点击segControl,虚线框会消失;点击屏幕的任何地方,虚线框和segControl都会消失。除了界面有点丑外,算是基本实现了预期效果。

    正文:

    我们希望的是:当手指在屏幕上移动时,虚线框随着手指的移动而生成。两个关键问题:手指移动时怎么触发画图机制?怎么绘制虚线框?

    一、手指移动的检测

    不需要在@interface中继承什么,直接在.m文件中,实现以下几个方法即可。他们都是UIResponder的方法。

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

    当手指开始移动时,系统自动调用touchesBegan; 在手指移动过程中,touchesMoved; 手指移动结束,touchesEnded; 当有外来事件,如打入电话,touchesCancelled。

    唯一需要注意的是:这些都是系统自动调用的方法,不需要自己调用!
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"touchesBegan");
        _isMoved = false;//在本程序中,设置这个参数的目的是为了让虚线框适时消失
        _touch = [[touches anyObject]retain];
        startPoint = [_touch locationInView:self];//记录起始点,point是声明为全局变量
        [_segControl removeFromSuperview];
         [self setNeedsDisplay];   //重绘界面,目的在于让虚线框消失
    }
    
    //手指移动过程
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"touchesMoved");
        _isMoved = true;
        endPoint=[_touch locationInView:self];//记录结束点的坐标
        
        // 用结束点的坐标减去起始点的坐标我么得到一个矩形框的宽和高,声明一个点记录一下;
        finalPoint.x=endPoint.x-startPoint.x;
        finalPoint.y=endPoint.y-startPoint.y;
        // 调用重绘方法,setNeedsDisplay中会自动调用drawRect:,我们不能自己调用drawRect:
        [self setNeedsDisplay];
    }
    
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"touchesEnded");
        endPoint = [_touch locationInView:self];//记录起始点,point是声明为全局变量
        if(_isMoved){
            _segControl.frame = CGRectMake(endPoint.x-50,endPoint.y+5,100,35);
            [self addSubview:_segControl];
        }       
        _isMoved = false;
        [_touch release];
    }
    
    //当接收到系统中断时,这些方法都不是自己调用的
    -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"touchesCancelled");
    }

    二、虚线框的绘制
         上面的代码中,我们在两个地方都调用了这样一个方法:[self setNeedsDisplay],这是UIView提供的方法,表示需要开始重绘界面。它还有个类似的,叫setNeedsDisplayInRect,表示在一个矩形区域内重绘界面。

    这个方法的具体实现我们是不知道的,但我们知道的是,这个方法会自动调用drawRect:方法,界面重绘的具体操作都是在drawRect:中进行的。

    所以,我们要自己绘制界面必须调用setNeedsDisplay方法,并重写drawRect方法。

    //准备工作做好后,我们就要画虚线的矩形框了.我们需要重写drawRect方法。完整代码如下:
    - (void)drawRect:(CGRect)rect//这个rect参数是这个view在一个cotroller中的位置
    {
        NSLog(@"drawRect called ,%f %f %f %f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
        if(_isMoved == true){
            //获取绘图上下文-画板
            CGContextRef ref=UIGraphicsGetCurrentContext();
            //设置虚线
            float lengths[] = {10,10};
            CGContextSetLineDash(ref,2, lengths, 1);        
            //画截取线框
            CGContextAddRect(ref,CGRectMake(startPoint.x,startPoint.y,finalPoint.x,finalPoint.y));
            //设置颜色
            CGContextSetStrokeColorWithColor(ref,[UIColor redColor].CGColor);
            //设置线宽
            CGContextSetLineWidth(ref,3);
            CGContextStrokePath(ref);
        }

    在touchesMoved中,我将_isMoved设为true,重绘界面时,会画出矩形框;

    在touchesEnd中,将_isMoved设为false,那么它调用的重绘界面,就不会画矩形框,实现了矩形框的消失。

    三、区域截图

         这个实在是没有什么好讲的,直接附代码

    //截取图片
    -(UIImage *)cutImageFromOrignalImage
    {
        CGRect rect = CGRectMake(startPoint.x,startPoint.y,finalPoint.x,finalPoint.y);
        CGImageRef imgRef = CGImageCreateWithImageInRect([_orignalImage CGImage], rect);
        UIImage *img = [UIImage imageWithCGImage:imgRef];
        return img;
    }

    四、特别注意

         这个程序也算基本完成了。但是,有一点要注意,那就是这个上面显示的image,是怎么加上去的。

         一般情况下,我们都是直接用imageView.image = img,把图片添加进来,但是在这种需要在界面上绘图的情况,这种加图片的方法就不行了,不是加不上去,而是画不上矩形框,必须把这个img设为背景:

    self.backgroundColor = [UIColor colorWithPatternImage:_orignalImage];

    这个现象很奇怪,手指移动都能检测,也能触发绘图,segcontrol也能显示,但就是画不上矩形框。

    分析:在网上查了一下,貌似是drawRect:方法不能在UIImageView上画图。很奇怪哈,UIImageView继承自UIView,为什么不能再上面画图了?苹果官方文档上是这么说的:UIImageView是专门为显示图片做的控件,用了最优显示技术,是不让调用darwrect方法的, 要调用这个方法,只能从UIView里重写。

    但我之前猜测以为可能是图层layer问题吧,就查了下,发觉这块也有很多东西应该学习。

    可以考虑看一下 CALayer和UIView 这2者的联系和区别,到时候可参考这篇博客http://www.cnblogs.com/lovecode/articles/2249548.html

  • 相关阅读:
    1008: 约瑟夫问题
    1009: 恺撒Caesar密码
    1006: 日历问题
    1007: 生理周期
    Asp.Net Core 发布和部署( MacOS + Linux + Nginx )
    ASP.NET Core Docker部署
    Asp.Net Core 发布和部署(Linux + Jexus )
    ASP.NET Core 十种方式扩展你的 Views
    基于机器学习的web异常检测
    Disruptor深入解读
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/3189821.html
Copyright © 2011-2022 走看看