美文网首页iOS记录
Swift-给视图添加水印(仿钉钉)

Swift-给视图添加水印(仿钉钉)

作者: 闲云悠鹤蝶恋舞 | 来源:发表于2021-03-12 11:01 被阅读0次

场景:

为了防止内部资料外传泄露用户信息,因此需要在视图上面添加相应的水印。


image.png

代码实现:

import UIKit

open class JJWatermark: UIImageView {
    
    /* 这三个属性 主要是让水印文字和水印文字之间间隔的效果,以及水印的文字的倾斜角度 ,不设置默认为平行角度*/
    private var horizontalSpaceing: CGFloat = 60 //水平间距
    private var verticalSpaceing: CGFloat = 40 //竖直间距
    private var cgTransformRotating: CGFloat = CGFloat.pi/12 //旋转角度(正旋15度 || 反旋15度)
    
    // 水印的文案、图片的参数配置
    private var text: String? = ""
    private var imageNamed: String? = ""
    private var attributes: [NSAttributedString.Key : Any]?
    
    
   
    /// 初始化方法
    ///   - imageNamed: 水印的图片
    ///   - horizontalSpaceing: 水平间距,默认值为60
    ///   - verticalSpaceing: 竖直间距,默认值为40
    ///   - cgTransformRotating: 旋转角度,默认正旋15°
    ///   - alpha: 水印的alpha,默认值1.0
    public init(frame: CGRect,
         text: String? = "",
         attributes: [NSAttributedString.Key : Any]? = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12.0),
                                                        NSAttributedString.Key.foregroundColor: UIColor.init(red: 225.0/255.0, green: 224.0/255.0, blue: 223.0/255.0, alpha: 0.3)
                                            ],
         imageNamed: String? = "",
         horizontalSpaceing: CGFloat = 60,
         verticalSpaceing: CGFloat = 40,
         cgTransformRotating: CGFloat = -CGFloat.pi/12,
         alpha: CGFloat = 1
         ) {
        super.init(frame: frame)
        
        self.text = text
        self.attributes = attributes
        self.imageNamed = imageNamed
        self.horizontalSpaceing = horizontalSpaceing
        self.verticalSpaceing = verticalSpaceing
        self.cgTransformRotating = cgTransformRotating
        self.alpha = alpha
        
        self.image = waterImage()
    }
    

    
    
    
    
    
    fileprivate func waterImage() -> UIImage {
        
        let image = UIImage(named: self.imageNamed ?? "") ?? UIImage()
    
        //设置水印大小,可以根据图片大小或者view大小
        let img_w = self.bounds.size.width
        let img_h = self.bounds.size.height
        
         //1.开启上下文
        //    UIGraphicsBeginImageContext(CGSizeMake(img_w, img_h));
        UIGraphicsBeginImageContextWithOptions(CGSize(width: img_w, height: img_h), false, 0.0)
        
        
        //2.绘制图片 水印图片
        image.draw(in: CGRect(x: 0, y: 0, width: img_w, height: img_h))

         /* --添加水印文字样式--*/
        let attrStr = NSMutableAttributedString(string: text ?? "", attributes: attributes)

        //文字:字符串的宽、高
        let str_w = attrStr.size().width
        let str_h = attrStr.size().height

        //根据中心开启旋转上下文矩阵,绘制水印文字
        if let context = UIGraphicsGetCurrentContext() {
            //将绘制原点(0,0)调整到源image的中心
            context.concatenate(CGAffineTransform(translationX: img_w/2, y: img_h/2))
            
            //以绘制原点为中心旋转
            context.concatenate(CGAffineTransform(rotationAngle: cgTransformRotating))
            
            //将绘制原点恢复初始值,保证context中心点和image中心点处在一个点(当前context已经发生旋转,绘制出的任何layer都是倾斜的)
            context.concatenate(CGAffineTransform(translationX: -img_w/2, y: -img_h/2))
            
            //sqrtLength:原始image对角线length。在水印旋转矩阵中只要矩阵的宽高是原始image的对角线长度,无论旋转多少度都不会有空白。
            let sqrtLength = sqrt(img_w*img_w + img_h*img_h)
            
            //计算需要绘制的列数和行数
            let count_Hor = sqrtLength / (str_w + CGFloat(horizontalSpaceing)) + 1
            let count_Ver = sqrtLength / (str_h + CGFloat(verticalSpaceing)) + 1

            //此处计算出需要绘制水印文字的起始点,由于水印区域要大于图片区域所以起点在原有基础上移
            let orignX = -(sqrtLength-img_w)/2
            let orignY = -(sqrtLength-img_h)/2
            
            
            //在每列绘制时X坐标叠加
            var overlayOrignX = orignX
            //在每行绘制时Y坐标叠加
            var overlayOrignY = orignY
            
            for i in 0..<Int(count_Hor * count_Ver) {
                //绘制图片
                let tempText = NSString(string: text ?? "")
                
                tempText.draw(in: CGRect(x: overlayOrignX, y: overlayOrignY, width: str_w, height: str_h), withAttributes: attributes)
                
                if (i % Int(count_Hor) == 0 && i != 0) {
                    overlayOrignX = orignX
                    overlayOrignY += (str_h + CGFloat(verticalSpaceing))
                }else{
                    overlayOrignX += (str_w + CGFloat(horizontalSpaceing))
                }
            }
            
            //3.从上下文中获取新图片
            let newImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()

            if let currentContent = UIGraphicsGetCurrentContext() {
                self.layer.render(in: currentContent)
                //4.关闭图形上下文
                UIGraphicsEndImageContext()
                context.saveGState()
                context.restoreGState()
            }
            
            return newImage
        }

        return UIImage()
    }
    
    
    
    
    
    
    
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
  
}

使用示例:

let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13.0),
                          NSAttributedString.Key.foregroundColor: UIColor.lightGray
        ]
// 不使用图片时,imageNamed的值不需要传
let watermark = IKMWatermark(frame: self.view.bounds, text: "添加水印", attributes: attributes, imageNamed: "6", horizontalSpaceing: 30, verticalSpaceing: 50, cgTransformRotating: -CGFloat.pi/12, alpha: 0.4)
self.view.addSubview(watermark)

相关文章

网友评论

    本文标题:Swift-给视图添加水印(仿钉钉)

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