• Quartz2D之生成圆形头像、打水印、截图三种方法的封装


    我给UIImage类添加了一个类目,用于封装三个方法,每个方法都没有难度,做这个主要为了练习一下封装;

    首先在类目.h文件中声明三个方法:以及创建了一个枚举、用于水印方法中设定水印位置;方法说明和参数都在下面注释好了

     1 typedef enum:NSUInteger{
     2     XQGConrnerTopLeftType,//左上角
     3     XQGConrnerTopRightType,//右上角
     4     XQGConrnerBottomLeftType,//左下角
     5     XQGConrnerBottomRightType,//右下角
     6 } XQGConrnerType;
     7 
     8 @interface UIImage (XQGQuartz2D)
     9 
    10 
    11 /**
    12  *  得到一张带水印的图片
    13  *
    14  *  @param waterIMG       水印图片
    15  *  @param bacIMG         背景图片
    16  *  @param size           水印距离某个角的边距
    17  *  @param XQGConrnerType 水印靠近背景哪个角上
    18  *  @param scale          缩放比例,不缩放为1
    19  *
    20  *  @return UIImage
    21  */
    22 + (instancetype)getWatermarkImageWithWaterImage:(UIImage *)waterIMG
    23                                        andImage:(UIImage *)bacIMG
    24                                         andDistance:(CGSize)size
    25                                       andWhichCorner:(XQGConrnerType)XQGConrnerType
    26                                             andScale:(CGFloat)scale;
    27 
    28 /**
    29  *  得到一张带边框的圆角头像
    30  *
    31  *  @param image  制作头像的图片
    32  *  @param radius 头像半径
    33  *  @param border 边框厚度,0为没有
    34  *  @param color  边框颜色
    35  *
    36  *  @return UIImage
    37  */
    38 + (instancetype)getCircleIconWithImage:(UIImage *)image
    39                               andRadius:(CGFloat)radius
    40                               andBorder:(CGFloat)border
    41                                andColor:(UIColor *)color;
    42 /**
    43  *  截图
    44  *
    45  *  @param view 需要被截图的view
    46  *
    47  *  @return UIImage
    48  */
    49 + (void)ScreenshotsWithView:(UIView *)view andImage:(XQGBlock)image

    接下来是水印方法的实现

     1  //开启上下文:基于位图(bitmap),所有的东西需要绘制到一张新的图片上去
     2     //size:新图片的尺寸
     3     //opaque:yes:不透明,no:透明
     4     //scale:伸缩尺寸;
     5     UIGraphicsBeginImageContextWithOptions(bacIMG.size, NO, 0.0);
     6     //画背景,背景大小即背景图片尺寸
     7     [bacIMG drawInRect:CGRectMake(0, 0, bacIMG.size.width, bacIMG.size.height)];
     8     //画水印,scale为1时水印大小等于原水印图片大小;
     9     CGFloat waterX;
    10     CGFloat waterY;
    11     CGFloat waterW = waterIMG.size.width * scale;
    12     CGFloat waterH = waterIMG.size.height * scale;
    13     //根据位置参数设定水印位于哪个角落,以及边距
    14     switch (XQGConrnerType) 
    15         case XQGConrnerBottomLeftType:
    16             waterX = size.width;
    17             waterY = bacIMG.size.height - size.height - waterIMG.size.height;
    18             break;
    19         case XQGConrnerTopLeftType:
    20             waterX = size.width;
    21             waterY = size.height;
    22             break;
    23         case XQGConrnerBottomRightType:
    24             waterX = bacIMG.size.width - size.width - waterIMG.size.width;
    25             waterY = bacIMG.size.height - size.height - waterIMG.size.height;
    26             break;
    27         case XQGConrnerTopRightType:
    28             waterX = bacIMG.size.width - size.width - waterIMG.size.width;
    29             waterY = size.height;
    30             break;
    31             
    32         default:
    33             break;
    34     }
    35     //把水印保存到上下文中
    36     [waterIMG drawInRect:CGRectMake(waterX , waterY, waterW, waterH)];
    37     //从上下文中取得制作完毕的UIImage对象
    38     UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    39     return newImage;

    生成头像方法的实现:

     1 + (instancetype)getCircleIconWithImage:(UIImage *)image andRadius:(CGFloat)radius andBorder:(CGFloat)border andColor:(UIColor *)color
     2 {
     3     CGSize size = CGSizeMake(2 * radius, 2 * radius);
     4     UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
     5 
     6     //取得上下文
     7     CGContextRef ctx = UIGraphicsGetCurrentContext();
     8     //保存一个初始状态
     9     CGContextSaveGState(ctx);
    10     //画裁剪范围
    11     CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, size.width, size.height));
    12     //裁剪
    13     CGContextClip(ctx);
    14     //画图片
    15     [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    16     //设置圆环,设置的为内圆环
    17     //释放初始状态
    18 CGContextRestoreGState(ctx);
    19 //radius - border * 2设为圆环半径,头像总半径才能保持为radius,因为设置线段宽度为内外增加相同厚度;
    20     CGContextAddArc(ctx, radius, radius, radius - border * 2, 0, M_PI * 2, 0);
    21     CGContextSetLineWidth(ctx,  border);
    22     [color setStroke];
    23     CGContextStrokePath(ctx);
    24     //从上下文中取得制作完毕的UIImage对象
    25     UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    26     //关闭上下文
    27     UIGraphicsEndImageContext();
    28     
    29     return newImage;
    30 }

    3、截图的方法实现:因为考虑到可能会截取到截取按钮的高亮状态,所以方法延迟0.5秒执行;并且使用了block块来传image对象;
    block定义为:Typedef void(^XQGBlock)(UIImage *image)

     1 +(void)ScreenshotsWithView:(UIView *)view andImage:(XQGBlock)image
     2 {
     3     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
     4         //1、开启上下文
     5         UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, 0.0);
     6         //2、将控制器view的layer渲染到上下文,想要截啥就把哪个图层拿出来渲染
     7         [view.layer renderInContext:UIGraphicsGetCurrentContext()];
     8         //3、取出图片
     9         UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    10         //关闭上下文
    11         UIGraphicsEndImageContext();
    12         image(newImage);
    13     });
    14 }

    实现效果:

    水印:设置水印位于右上角,缩放0.8,距离上右边界为10;水印图片;

    [UIImage getWatermarkImageWithWaterImage:water andImage:bacimage andDistance:CGSizeMake(10, 10) andWhichCorner:XQGConrnerTopRightType andScale:0.8];

    输出结果;

     

     

    头像:设置头像半径为40,描边厚度为2、黑色

    [UIImage getCircleIconWithImage:icon andRadius:40 andBorder:2 andColor:[UIColor blackColor]];

    截图:把需要截图的view带进去即可;在block回调中获取图片进行操作即可,我的为保存到桌面;就不放图了;

    [UIImage ScreenshotsWithView:self.viewIMG andImage:^(UIImage *image) {

            NSData * data = UIImagePNGRepresentation(image);

            [data writeToFile:@"/Users/ibokan/Desktop/icon.png" atomically:YES];

        }];

     

    好了,这样就完成了。早日脱离小白!加油!

     

  • 相关阅读:
    为什么我要迁移 SpringBoot 到函数计算
    PolarDBX源码解读系列:DML之Insert流程
    转载 | 从云计算到函数计算
    通过部署流行Web框架掌握Serverless技术
    阿里云云原生一体化数仓 — 湖仓一体新能力解读
    EasyNLP中文文图生成模型带你秒变艺术家
    转载 | 基于函数计算自定义运行时快速部署一个 springboot 项目
    PolarDBX 源码解读:事务的一生
    【20220319】回老家给父亲庆生
    【20220321】连岳摘抄
  • 原文地址:https://www.cnblogs.com/xiaoqiuge/p/4845221.html
Copyright © 2020-2023  润新知