zoukankan      html  css  js  c++  java
  • iOS 绘图 (UIImage的一些操作)

    UIGraphicsBeginImageContextWithOptions,本文主要在图片类型上下文中对图片进行操作,具体实现的功能:

    •  - 1.生成图片
    •  - 2.绘制图片到视图
    • - 3.添加水印
    • - 4.截取屏幕或者相应view
    • - 5.图片擦除
    • - 6.图片裁剪

    具体的方法使用就在方法的介绍中解释吧,为了代码的复用,对上述方法进行了封装,放在UIImage的类别中,方便今后使用。

    图片操作的基本步骤

    1.开启图形上下文
    2.绘制图片
    - 使用drowInRect或者drawAtPoint绘制图片(区别在哪儿?你可以先想一想)
     drawInRect是以rect作为图片绘制的区域,图片是以填充的方式被绘制在当前区域图片的大小,rect的宽高比和原图片的宽高比不同时会造成图片的变形
     drowAtPoint是以point作为图片绘制的起点,绘制的图片的大小依然是原图片的大小,不会使图片变形
    - 将layer渲染在当前上下文
    3.从当前上下文获取新的图片
    4.关闭上下文

    1.生成图片,这里我们生成特定颜色的图片

    + (UIImage *)createImageColor:(UIColor *)color size:(CGSize)size {
        //开启图形上下文
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
        //绘制颜色区域
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, size.width, size.height)];
        [color setFill];
        [path fill];
    //    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //    CGContextSetFillColorWithColor(ctx, color.CGColor);
    //    CGContextFillRect(ctx, CGRectMake(0, 0, size.width, size.height));
        //从图形上下文获取图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        //关闭图形上下文
        UIGraphicsEndImageContext();
    
        return newImage;
    }

    2.绘制图片,可以设置绘制的图片比例或者指定压缩后的图片的大小,可以当做压缩图片使用

    + (UIImage *)scaleImage:(UIImage *)image sclae:(CGFloat)scale {
        //确定压缩后的size
        CGFloat scaleWidth = image.size.width * scale;
        CGFloat scaleHeight = image.size.height * scale;
        CGSize scaleSize = CGSizeMake(scaleWidth, scaleHeight);
        //开启图形上下文
        UIGraphicsBeginImageContext(scaleSize);
        //绘制图片
        [image drawInRect:CGRectMake(0, 0, scaleWidth, scaleHeight)];
        //从图形上下文获取图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        //关闭图形上下文
        UIGraphicsEndImageContext();
        return newImage;
    }

    3.绘制水印

    文字水印

    可能你在添加文字水印之后,显示文字字体并不是你设置的字体大小,这是因为画布的size是图片的size,绘制后的图片被添加到ImageView上时可能被压缩或者放大,文字也就会发生变化。

    + (UIImage *)waterAtImage:(UIImage *)image
                       text:(NSString *)text
                      point:(CGPoint)point
                 attributes:(NSDictionary *)attributes {
        //开启图形上下文
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        //绘制图片
        [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
        //添加文字
        [text drawAtPoint:point withAttributes:attributes];
        //获取图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        //关闭上下文
        UIGraphicsEndImageContext();
        return newImage;
    }

    图片水印

    + (UIImage *)waterAtImage:(UIImage *)image
                 waterImgae:(UIImage *)waterImage
                       rect:(CGRect)rect {
        //开启图形上下文
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        //绘制原图片
        [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.width)];
        //绘制水印
        [waterImage drawInRect:rect];
    
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }

    4.截屏

    1.创建图形上下文
    
    2.将view的layer渲染到图形上下文
    
    3.从图形上下文得到图片
    
    4.关闭图像上下文

    //当然如果你只是需要某个view的快照,在iOS7之后你可以使用[view snapshotViewAfterScreenUpdates:NO];来获得,比如实现长按拖拽cell的操作

    + (void)cutView:(UIView *)view success:(void(^)(UIImage *image))success {
        //开启图形上下文
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);
        //获取当前上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //渲染
        [view.layer renderInContext:ctx];
    
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        success(newImage);
    }

    5.擦除

    1.设置两张图片,上方为我们要擦除的图片,后方为需要展示的图片
    2.设置擦除的区域的大小和位置

    + (UIImage *)wipeView:(UIView *)view
                    point:(CGPoint)point
                     size:(CGSize)size {
        //开启图形上下文
        UIGraphicsBeginImageContext(view.bounds.size);
        //获取当前上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //渲染
        [view.layer renderInContext:ctx];
        //计算擦除的rect
        CGFloat clipX = point.x - size.width/2;
        CGFloat clipY = point.y - size.height/2;
        CGRect clipRect = CGRectMake(clipX, clipY, size.width, size.height);
        //将该区域设置为透明
        CGContextClearRect(ctx, clipRect);
        //获取新的图片
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
        return newImage;
    }

    6.图片裁剪

    矩形区域的裁剪,这里我们就利用drowAtPoint的特性去进行裁剪

    1.假设一张图片的size是(600,600)
    2.imageView的size是(300,300)
    3.我们选择的裁剪区域是(10,10,150,150)
    4.而我们为了能够保持原来图片的分辨率,在图片不拉伸的情况下在原图片上进行剪裁,所以实际我们在图片上的剪裁区域就是(20,20,300,300)
    5.图片绘制在画布上的点就是(-20,-20),这样我们不需要进行裁剪就能获得我们想要得到的图片啦
    + (UIImage *)cutImage:(UIImage *)image
            imageViewSize:(CGSize)size
                 clipRect:(CGRect)rect {
        //图片大小和实际显示大小的比例
        CGFloat scale_width = image.size.width/size.width;
        CGFloat scale_height = image.size.height/size.height;
        //实际剪切区域
        CGRect clipRect = CGRectMake(rect.origin.x * scale_width,
                                     rect.origin.y * scale_height,
                                     rect.size.width * scale_width,
                                     rect.size.height * scale_height);
    
        //开启图形上下文
        UIGraphicsBeginImageContext(clipRect.size);
        //画图
        [image drawAtPoint:CGPointMake(-clipRect.origin.x, -clipRect.origin.y)];
    
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return newImage;
    }

    自定义点连线截图

    1.将自定义点变换到在图片上的点
    2.计算出自定义点所在的区域rect
    3.开始图形上下文,rect.size
    4.绘制path,机型剪裁
    5.绘图drawAtPoint,x: - rect.origin.x y: - rect.origin.y
    6.从图形上下文获取图片
    7.关闭图形上下文
    + (UIImage *)cutImage:(UIImage *)image
            imageViewSize:(CGSize)size
               clipPoints:(NSArray *)points {
        //图片大小和实际显示大小的比例
        CGFloat scale_width = image.size.width/size.width;
        CGFloat scale_height = image.size.height/size.height;
    
        //处理剪裁的点
        NSArray *newPoints = [UIImage points:points scalex:scale_width scaleY:scale_height];
    
        //确定上下左右边缘的点
        //x升序数组
        NSArray *point_x = [newPoints sortedArrayUsingComparator:^NSComparisonResult(NSValue *obj1, NSValue *obj2) {
            CGPoint point1 = [obj1 CGPointValue];
            CGPoint point2 = [obj2 CGPointValue];
            return point1.x > point2.x;
        }];
        //y升序数组
        NSArray *point_y = [newPoints sortedArrayUsingComparator:^NSComparisonResult(NSValue *obj1, NSValue *obj2) {
            CGPoint point1 = [obj1 CGPointValue];
            CGPoint point2 = [obj2 CGPointValue];
            return point1.y > point2.y;
        }];
    
        //确定剪切的区域
        CGRect clipRect = CGRectMake([point_x.firstObject CGPointValue].x,
                                     [point_y.firstObject CGPointValue].y,
                                     [point_x.lastObject CGPointValue].x - [point_x.firstObject CGPointValue].x,
                                     [point_y.lastObject CGPointValue].y - [point_y.firstObject CGPointValue].y);
        //开启图形上下文
        UIGraphicsBeginImageContext(clipRect.size);
    
        UIBezierPath *path = [UIBezierPath bezierPath];
        for (NSInteger i = 0; i < newPoints.count; i ++) {
            CGPoint point = [newPoints[i] CGPointValue];
            if (i == 0) {
                [path moveToPoint:point];
            } else {
                [path addLineToPoint:point];
            }
        }
        [path closePath];
        [path addClip];
    
        //画图
        [image drawAtPoint:CGPointMake(-clipRect.origin.x, -clipRect.origin.y)];
    
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
        return newImage;
    }
    
    
    原文作者:
    作者:莫须有恋
    链接:http://www.jianshu.com/p/3baddf100b67
  • 相关阅读:
    Docker配置容器位置和小技巧
    firewall防火墙
    iptables防火墙常用命令
    Docker 常用命令
    Dockerfile镜像的制作
    Windows和Centos下Docker的安装配置
    ubuntu 常用命令
    microPython环境安装及使用
    Arduino上“Collect2.exe: error: ld returned 5 exit status”错误的解决方法
    基于C语言的面向对象编程
  • 原文地址:https://www.cnblogs.com/wlsxmhz/p/7778011.html
Copyright © 2011-2022 走看看