iOS开发之在列表上方添加水印的方法

前言

为了防止工程师泄露用户信息,我们有个需求是在列表上面添加水印。我封装了这个视图分享出来。下面话不多说了,来一起看看详细的介绍吧

效果图

示例代码如下:

watermarkView.h

#import <UIKit/UIKit.h>

@interface watermarkView : UIImageView

/**
 设置水印

 @param frame 水印大小
 @param markText 水印显示的文字
 */
- (instancetype)initWithFrame:(CGRect)frame WithText:(NSString *)markText;

@end

watermarkView.m

#import "watermarkView.h"

#define HORIZONTAL_SPACE 30//水平间距
#define VERTICAL_SPACE 50//竖直间距
#define CG_TRANSFORM_ROTATION (M_PI_2 / 3)//旋转角度(正旋45度 || 反旋45度)

@implementation watermarkView

- (instancetype)initWithFrame:(CGRect)frame WithText:(NSString *)markText{
 if(self = [super initWithFrame:frame]){

  UIFont *font = [UIFont systemFontOfSize:14];

  UIColor *color = YTHColorAlpha(152, 152, 152, 0.1);

  //原始image的宽高
  CGFloat viewWidth = frame.size.width;
  CGFloat viewHeight = frame.size.height;

  //为了防止图片失真,绘制区域宽高和原始图片宽高一样
  UIGraphicsBeginImageContext(CGSizeMake(viewWidth, viewHeight));

  //sqrtLength:原始image的对角线length。在水印旋转矩阵中只要矩阵的宽高是原始image的对角线长度,无论旋转多少度都不会有空白。
  CGFloat sqrtLength = sqrt(viewWidth*viewWidth + viewHeight*viewHeight);
  //文字的属性
  NSDictionary *attr = @{
        //设置字体大小
        NSFontAttributeName: font,
        //设置文字颜色
        NSForegroundColorAttributeName :color,
        };
  NSString* mark = markText;
  NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:mark attributes:attr];
  //绘制文字的宽高
  CGFloat strWidth = attrStr.size.width;
  CGFloat strHeight = attrStr.size.height;

  //开始旋转上下文矩阵,绘制水印文字
  CGContextRef context = UIGraphicsGetCurrentContext();

  //将绘制原点(0,0)调整到原image的中心
  CGContextConcatCTM(context, CGAffineTransformMakeTranslation(viewWidth/2, viewHeight/2));
  //以绘制原点为中心旋转
  CGContextConcatCTM(context, CGAffineTransformMakeRotation(CG_TRANSFORM_ROTATION));
  //将绘制原点恢复初始值,保证当前context中心和源image的中心处在一个点(当前context已经旋转,所以绘制出的任何layer都是倾斜的)
  CGContextConcatCTM(context, CGAffineTransformMakeTranslation(-viewWidth/2, -viewHeight/2));

  //计算需要绘制的列数和行数
  int horCount = sqrtLength / (strWidth + HORIZONTAL_SPACE) + 1;
  int verCount = sqrtLength / (strHeight + VERTICAL_SPACE) + 1;

  //此处计算出需要绘制水印文字的起始点,由于水印区域要大于图片区域所以起点在原有基础上移
  CGFloat orignX = -(sqrtLength-viewWidth)/2;
  CGFloat orignY = -(sqrtLength-viewHeight)/2;

  //在每列绘制时X坐标叠加
  CGFloat tempOrignX = orignX;
  //在每行绘制时Y坐标叠加
  CGFloat tempOrignY = orignY;
  for (int i = 0; i < horCount * verCount; i++) {
   [mark drawInRect:CGRectMake(tempOrignX, tempOrignY, strWidth, strHeight) withAttributes:attr];
   if (i % horCount == 0 && i != 0) {
    tempOrignX = orignX;
    tempOrignY += (strHeight + VERTICAL_SPACE);
   }else{
    tempOrignX += (strWidth + HORIZONTAL_SPACE);
   }
  }
  //根据上下文制作成图片
    UIImage *finalImg = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  CGContextRestoreGState(context);

  self.image = finalImg;
 }

 return self;
}

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{

 //1.判断自己能否接收事件
 if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {
  return nil;
 }
 //2.判断当前点在不在当前View.
 if (![self pointInside:point withEvent:event]) {
  return nil;
 }
 //3.从后往前遍历自己的子控件.让子控件重复前两步操作,(把事件传递给,让子控件调用hitTest)
 int count = (int)self.subviews.count;
 for (int i = count - 1; i >= 0; i--) {
  //取出每一个子控件
  UIView *chileV = self.subviews[I];
  //把当前的点转换成子控件坐标系上的点.
  CGPoint childP = [self convertPoint:point toView:chileV];
  UIView *fitView = [chileV hitTest:childP withEvent:event];
  //判断有没有找到最适合的View
  if(fitView){
   return fitView;
  }
 }

 //4.没有找到比它自己更适合的View.那么它自己就是最适合的View
 return self;
}

//作用:判断当前点在不在它调用View,(谁调用pointInside,这个View就是谁)
//什么时候调用:它是在hitTest方法当中调用的.
//注意:point点必须得要跟它方法调用者在同一个坐标系里面
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
 NSLog(@"%s",__func__);
 return NO;
}

使用方法

 //加水印
 watermarkView *watermark = [[watermarkView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, KScreenH) WithText:@"测试"];
 [self.view addSubview:watermark];

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

时间: 2018-08-03

浅析iOS给图片加水印的方法

话不多说,直接上代码 新建了一个UIImage的类目,在.h中声明 + (UIImage *)imageWithimage:(UIImage *)image content:(NSString *)content frame:(CGRect)frame; .m如下 + (UIImage *)imageWithimage:(UIImage *)image content:(NSString *)content frame:(CGRect)frame { // 开启图形'上下文' UIGraphic

IOS给图片添加水印(两种方式)

为了防止自己辛苦做的项目被别人盗走,采取图片添加水印,在此表示图片的独一无二.加水印不是在上面添加几个Label,而是我们把字画到图片上成为一个整体,下面小编给大家分享IOS给图片添加水印(两种方式). 提供一个方法,此方法只需要传递一个要加水印的图片和水印的内容就达到效果. 第一种方式: -(UIImage *)watermarkImage:(UIImage *)img withName:(NSString *)name { NSString* mark = name; int w = img

iOS实现图片水印与简单封装示例代码

前言: 常用的许多软件中图片加水印的功能是非常常见的,如微博,微信,今日头条等等图片上都会有. 首先我们了解一下什么是水印及其作用? 水印:在图片上加的防止他人盗图的半透明logo.文字.图标 水印的作用:告诉你这个图片从哪来的,主要是一些网站为了版权问题.广告而添加的. 相关知识点:Quartz2D相关内容 核心代码: 将字符串添加到图形上下文的方法 - (void)drawAtPoint:(CGPoint)point withAttributes:(nullable NSDictionary

基于Vue2x的图片预览插件的示例代码

本文介绍了基于Vue2x的图片预览插件的示例代码,分享给大家,具体如下: 先来看下Demo LiveDemo 关于开发Vue插件的几种方式 (具体请移步官网)Vue官网 MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, bin

weui上传多图片,压缩,base64编码的示例代码

记录一下在做一个报修功能的心路历程,需求功能很简单,一个表单提交,表单包含简单的文字字段以及图片 因为使用的是weui框架,前面的话去找weui的表单和图片上传组件,说实话,weui的组件写的还不错,作为一个不太懂前端的渣渣可以拿来开箱即用 主要是不用调那么多的样式问题,直接上代码: <div class="weui-cell"> <div class="weui-cell__bd"> <div class="weui-upl

Java实现图片转换PDF文件的示例代码

最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就直接使用Java写了一个图片转换PDF的系统,现在将该系统分享在这里. 引入依赖 <!--该项目以SpringBoot为基础搭建--> <parent> <groupId>org.springframework.boot</groupId> <artifa

IOS获取系统相册中照片的示例代码

先来看看效果图 下面话不多少,我们直接上代码: #import "ViewController.h" @interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate> @property (weak, nonatomic) IBOutlet UIImageView *IconView; @end @implementation ViewController

iOS UIPickerView的简单封装示例

前言 在iOS实际项目中,经常会出现界面中多个地方需要使用UIPickerView,如果在每个需要用到的地方都创建一个UIPickerView不仅更耗性能,而且还会让你的代码变得更加杂乱.冗余,因此我在这里向大家介绍一下我对UIPickerView的一些简单封装. 所需属性 /** pickerView*/ @property (nonatomic, strong) UIPickerView pickerView; /* pickerView背景*/ @property (nonatomic,

iOS中视频播放器的简单封装详解

前言 如果仅仅是播放视频两者的使用都非常简单,但是相比MediaPlayer,AVPlayer对于视频播放的可控制性更强一些,可以通过自定义的一些控件来实现视频的播放暂停等等.因此这里使用AVPlayer的视频播放. 视频播放器布局 首先使用xib创建CLAVPlayerView继承UIView用来承载播放器,这样我们在外部使用的时候,直接在控制器View或者Cell上添加CLAVPlayerView即可,至于播放器播放或者暂停等操作交给CLAVPlayerView来管理.下面来看一下CLAVP

iOS下拉选择菜单简单封装

本文实例为大家分享了简单封装的iOS下拉选择菜单代码,供大家参考,具体内容如下 // // OrderListDownMenu.h #import <UIKit/UIKit.h> @protocol OrderListDownMenuDelegate <NSObject> - (void)OrderListDownMenu:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; @end

PHP图片水印类的封装

封装PHP的图片水印的类,供大家参考,具体内容如下 <?php header('Content-type:text/html;charset=utf8'); $img = new Image(); // $img->water('2a.jpg','logo.gif',0); class Image{ //路径 protected $path; //是否启用随机名字 protected $isRandName; //要保存的图像类型 protected $type; //通过构造方法队成员属性进

nodejs连接mysql数据库简单封装示例-mysql模块

本人最近在学习研究nodejs,下面我来记录一下,有需要了解nodejs连接mysql数据库简单封装的朋友可参考.希望此文章对各位有所帮助. 安装mysql模块 npm install mysql 测试是否连接成功 mysql.js代码: var mysql = require('mysql'); var connection = mysql.createConnection({ host : 'localhost', user : 'root', password : '123456', da