美文网首页
iOS-创建位图上下文(Bitmap Graphics Cont

iOS-创建位图上下文(Bitmap Graphics Cont

作者: Imkata | 来源:发表于2019-11-11 19:25 被阅读0次

    CoreGraphics图形库里面说过,CoreGraphics提供了以下几种类型的图形上下文:

    1. 位图图形上下文:Bitmap Graphics Context
    2. PDF图形上下文:PDF Graphics Context
    3. window图形上下文:Window Graphics Context
    4. layer层图形上下文:Layer Graphics Context
    5. 打印图形上下文:Printer Graphics Context

    CoreGraphics图形库这一章,我们都是通过自定义View,在它的drawRect方法里面获取当前的上下文(Layer Graphics Context)来进行操作的,所以绘制的东西会显示到layer上面。

    只要上下文不同,绘制的地方就不同。

    下面我们介绍如何创建位图上下文(Bitmap Graphics Context),位图上下文其实可以理解为一个图片,我们获取到位图上下文可以进行好多图片相关的操作。

    1. 创建位图上下文的方法

    UIGraphicsBeginImageContext(<#CGSize size#>);
    
    UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
    //CGSize size:指定将来创建出来的bitmap的大小
    //BOOL opaque:默认为YES,不透明,位图中没有绘制的区域会以黑色显示;NO代表透明,位图中没有绘制的区域会以透明显示;主要是用于绘图时进行性能优化的开关。
    //CGFloat scale:代表缩放,0代表系统会自动设置根据当前设备的屏幕因数设置缩放因数
    
    1. 使用这两个方法同样都可以创建,但是使用第二个方法创建的图片清晰度和质量比较高。
    2. 创建出来的bitmap就对应一个UIImage对象。

    简单举例,下面我们创建一个位图上下文,然后在这个位图上下文上画一个圆圈,然后把图片保存到本地桌面,代码如下:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //创建一个Bitmap上下文
    
        //C语言的方法
        //CGBitmapContextCreate(<#void *data#>, <#size_t width#>, <#size_t height#>, <#size_t bitsPerComponent#>, <#size_t bytesPerRow#>, <#CGColorSpaceRef space#>, <#CGBitmapInfo bitmapInfo#>)
    
        //OC中封装的方法:
        //方法1
        //UIGraphicsBeginImageContext(<#CGSize size#>);
        //方法2
        UIGraphicsBeginImageContextWithOptions( CGSizeMake(200, 200), NO, 0);
    
        //1.获取bitmap上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //2.绘图(画一个圆)
        CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100));
        //3.渲染
        CGContextStrokePath(ctx);
        //4.获取生成的图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        //5.显示生成的图片到imageview
        self.iv.image=image;
        //6.保存绘制好的图片到文件中
        // 先将图片转换为二进制数据,然后再将图片写到文件中
        // UIImageJPEGRepresentation(image, 1); //第二个参数为保存的图片的效果
        NSData *data = UIImagePNGRepresentation(image);
        [data writeToFile:@"/Users/xujincheng/Desktop/abc.png" atomically:YES];
    }
    
    效果图如下: 图片.png

    下面我们就通过创建位图上下文做一些其他有用的操作。

    2. 图片裁剪圆形

    给UIImage添加分类,实现传入一个图片,处理后,图片变成圆形有边框。

    代码:

    +(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 在自定义的view的drawRect方法里,调用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;
    }
    
    效果图: 圆形.png

    3. 截屏

    //屏幕截图
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        //截取当前vie成为一张图片
        
        // 使用位图上下文
        // 1.创建位图上下文
        UIGraphicsBeginImageContext(self.view.bounds.size);
        
        // 2.当前控制器的view画在位图上下文
        // render 渲染
        [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
        
        // 3.获取图片
        UIImage *captureImg = UIGraphicsGetImageFromCurrentImageContext();
        
        // 4.结束位图编辑
        UIGraphicsEndImageContext();
        
        //保存图片
        NSData *imgData = UIImagePNGRepresentation(captureImg);
    #warning 平时开发过程,图片保存是沙盒
        [imgData writeToFile:@"/Users/xujincheng/Desktop/capture.png" atomically:YES];
    }
    

    4. 图片裁剪

    #import "CircleImageController1.h"
    
    @interface CircleImageController1 ()
    
    @property (strong, nonatomic) UIImageView *imageV;
    //开始时手指的点
    @property (nonatomic, assign) CGPoint startP;
    
    //覆盖上面灰色的View
    @property (nonatomic, weak) UIView *coverV;
    
    @end
    
    @implementation CircleImageController1
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"图片裁剪";
        self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        self.imageV.userInteractionEnabled = YES;
        self.imageV.image = [UIImage imageNamed:@"haha.png"];
        [self.view addSubview:self.imageV];
        
        UIPanGestureRecognizer *ges = [[UIPanGestureRecognizer alloc] init];
        [ges addTarget:self action:@selector(panAction:)];
        [self.imageV addGestureRecognizer:ges];
    }
    
    //添加手势之后调用的方法
    - (void)panAction:(UIPanGestureRecognizer *)pan {
        
        //判断手势的状态
        CGPoint curP = [pan locationInView:self.imageV];
        if(pan.state == UIGestureRecognizerStateBegan) {
            self.startP = curP;
        } else if(pan.state == UIGestureRecognizerStateChanged) {
            
            CGFloat x = self.startP.x;
            CGFloat y = self.startP.y;
            CGFloat w = curP.x - self.startP.x;
            CGFloat h = curP.y - self.startP.y;
            CGRect rect =  CGRectMake(x, y, w, h);
            
            //添加一个UIView
            self.coverV.frame = rect;
            
        } else if (pan.state == UIGestureRecognizerStateEnded) {
            
            //把超过coverV的frame以外的内容裁剪掉
            //生成了一张图片,把原来的图片给替换掉.
            UIGraphicsBeginImageContextWithOptions(self.imageV.bounds.size, NO, 0);
            
            //把ImageV绘制到上下文之前,设置一个裁剪区域
            UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:self.coverV.frame];
            [clipPath addClip];
            
            //把当前的ImageView渲染到上下文当中
            CGContextRef ctx =  UIGraphicsGetCurrentContext();
            [self.imageV.layer renderInContext:ctx];
            //.从上下文当中生成 一张图片
            UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
            //关闭上下文
            UIGraphicsEndImageContext();
            
            self.imageV.image = newImage;
            [self.coverV removeFromSuperview];
        }
    }
    
    /**
     *  懒加载coverV
     *  1.能够保证超始至终只有一份
     *  2.什么时候用到什么时候才去加载
     */
    -(UIView *)coverV {
        
        if (_coverV == nil) {
            //添加一个UIView
            UIView *coverV = [[UIView alloc] init];
            coverV.backgroundColor = [UIColor blackColor];
            coverV.alpha = 0.7;
            _coverV = coverV;
            [self.view addSubview:coverV];
        }
        return _coverV;
    }
    @end
    
    效果图: 图片裁剪.png

    5. 图片擦除

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"图片擦除";
        self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(50, 100, 300, 300)];
        self.imageV.image = [UIImage imageNamed:@"papa.png"];
        self.imageV.userInteractionEnabled = YES;
        [self.view addSubview:self.imageV];
        
        //添加手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        [self.imageV addGestureRecognizer:pan];
    }
    
    - (void)pan:(UIGestureRecognizer *)pan {
        
        //获取当前手指的点
        CGPoint curP =  [pan locationInView:self.imageV];
        
        //确定擦除区域
        CGFloat rectWH = 30;
        CGFloat x = curP.x - rectWH * 0.5;
        CGFloat y = curP.y - rectWH * 0.5;
        CGRect rect = CGRectMake(x, y, rectWH, rectWH);
        
        //生成一张带有透明擦除区域的图片
        
        //1.开启图片上下文
        UIGraphicsBeginImageContextWithOptions(self.imageV.bounds.size, NO, 0);
        
        //2.把UIImageV内容渲染到当前的上下文当中
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        [self.imageV.layer renderInContext:ctx];
        
        //3.擦除上下文当中的指定的区域
        CGContextClearRect(ctx, rect);
        
        //4.从上下文当中取出图片
        UIImage *newImage =  UIGraphicsGetImageFromCurrentImageContext();
        
        //替换之前ImageView的图片
        self.imageV.image = newImage;
    }
    
    效果图: 图片擦除.png

    Demo地址:创建位图上下文

    相关文章

      网友评论

          本文标题:iOS-创建位图上下文(Bitmap Graphics Cont

          本文链接:https://www.haomeiwen.com/subject/yzfxictx.html