场景:
为了防止内部资料外传泄露用户信息,因此需要在视图上面添加相应的水印。
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)
网友评论