1、水印处理

给图片添加文字、图片水印

// 水印处理

- (void)shuiyin

{

// 水印处理

UIImage *image  = [UIImage imageNamed:@"4"];

UIImage *image2  = [UIImage imageNamed:@"010"];

CGFloat imageH = image.size.height;

CGFloat imageW = image.size.width;

// 获取位图上下文

UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);

// 绘制图形或者文字

[image drawAtPoint:CGPointZero];

NSString *str = @"@zhang@163.com";

CGFloat strlenth = str.length * 8;

// 文字水印

[str drawAtPoint:CGPointMake(imageW - strlenth, imageH - 44) withAttributes:nil];

// 图片水印

[image2 drawAtPoint:CGPointMake(imageW - strlenth - 66, imageH - 66)];

// 关闭位图上下文

UIGraphicsEndPDFContext();

// 获取位图

_imageView.image = UIGraphicsGetImageFromCurrentImageContext();

// 保存图片,需要转换成二进制数据

NSData *data = UIImageJPEGRepresentation(_imageView.image, 1); // 参数2表示图片质量

NSData *data1 = UIImagePNGRepresentation(_imageView.image); // png默认最高质量

// 写入文件

[data1 writeToFile:@"/Users/song/Desktop/me.png"atomically:YES];

}

2、图形裁切

首先设置一个裁切区域,然后在裁切区域显示图片。 

// 图形裁切

- (void)clipImage

{

// 获取图片

UIImage *image = [UIImage imageNamed:@"4"];

// 获取位图上下文

UIGraphicsBeginImageContextWithOptions(image.size,NO,0.0);

// 设置圆形裁剪区域,正切与图片

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];

// 添加裁切区域

[path addClip];

// 绘制图片

[ima drawAtPoint:CGPointZero];

// 从上下文获取图片

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

// 关闭位图上下文

UIGraphicsEndImageContext();

// 显示位图

_imageView.image = image;

}

带边框的圆形裁切

首先绘制一个红色的圆,然后在圆中心绘制图片,保留一定的边框。

// 带边框的原型裁切

- (void)cicleAroundImage

{

// 1、绘制一个大圆,设置背景色

// 获取图片

UIImage *ima = [UIImage imageNamed:@"4"];

// 图片宽高

CGFloat imageW = ima.size.width;

// 边界宽度

CGFloat boarder = 3;

// 圆环宽高

CGFloat cicleW = imageW + 2 * boarder;

// 获取位图上下文

UIGraphicsBeginImageContextWithOptions(CGSizeMake(cicleW, cicleW),NO,0.0);

// 绘制圆形

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, cicleW, cicleW)];

// 填充红色

[[UIColor redColor] set];

[path fill];

// 2、绘制图片,要比大圆小一点

UIBezierPath *clipArea = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(boarder , boarder, imageW, imageW)];

// 裁切

[clipArea addClip];

// 绘制图片

[ima drawAtPoint:CGPointMake(boarder, boarder)];

// 从上下文获取图片

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

// 关闭位图上下文

UIGraphicsEndImageContext();

// 显示位图

_imageView.image = image;

}

带有边框的裁切可以使用一个分类 

#import "UIImage+image.h"

@implementation UIImage (image)

+ (instancetype) imageWithImage:(UIImage *)image withBoard:(CGFloat )board withColor:(UIColor *)color

{

// 1、绘制一个大圆,设置背景色

// 获取图片

UIImage *ima = image;

// 图片宽高

CGFloat imageW = ima.size.width;

// 边界宽度

CGFloat boarder = board;

// 圆环宽高

CGFloat cicleW = imageW + 2 * boarder;

// 获取位图上下文

UIGraphicsBeginImageContextWithOptions(CGSizeMake(cicleW, cicleW),NO,0.0);

// 绘制圆形

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, cicleW, cicleW)];

// 填充红色

[color set];

[path fill];

// 2、绘制图片,要比大圆小一点

UIBezierPath *clipArea = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(boarder , boarder, imageW, imageW)];

// 裁切

[clipArea addClip];

// 绘制图片

[ima drawAtPoint:CGPointMake(boarder, boarder)];

// 从上下文获取图片

UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();

// 关闭位图上下文

UIGraphicsEndImageContext();

// 显示位图

return clipImage;

}

@end

 

使用起来也方便,直接包含头文件即可使用

#import "ViewController.h"

#import "UIImage+image.h"

@interfaceViewController ()

@property (weak, nonatomic) IBOutletUIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

// 使用分类

UIImage *ima = [UIImage imageWithImage:[UIImage imageNamed:@"4"] withBoard:3 withColor:[UIColor blueColor]];

_imageView.image = ima;

}

3、屏幕截图

主要是从控制器上获取图层。一定要使用 renderInContext: 进行渲染,不可使用draw...

// 屏幕截图

- (void)snipImage

{

//获取位图上下文

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);

// 获取当前上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

// 渲染控制器图层到图形上下文,把控件上的图层渲染到上下文,layer只能渲染

[self.view.layer renderInContext:ctx];

// 获取图形上下文

UIImage *snipImage = UIGraphicsGetImageFromCurrentImageContext();

// 关闭位图上下文

UIGraphicsEndImageContext();

NSData *data = UIImagePNGRepresentation(snipImage);

[data writeToFile:@"/Users/song/Desktop/snip.png"atomically:YES];

}

4、手势解锁

效果

4.1、界面

在storyboard里添加一个view用来显示九宫格

4.2、新建一个类继承自UIView

添加按钮

// 添加按钮

- (void)awakeFromNib

{

[super awakeFromNib];

// 创建按钮

for (NSInteger i = 0;  i < 9; i ++)

{

UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeCustom];

[btn setBackgroundImage:[UIImageimageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];

[btn setBackgroundImage:[UIImageimageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];

btn.userInteractionEnabled = NO;

btn.tag = i;

[self addSubview:btn];

}

}

设置按钮frame

// 九宫格按钮计算

- (void)layoutSubviews

{

[super layoutSubviews];

// 按钮个数

NSInteger count = self.subviews.count;

// 按钮宽度和高度

CGFloat x = 0;

CGFloat y = 0;

CGFloat w = 74;

CGFloat h = 74;

// 行

NSInteger cols = 3;

// 列

NSInteger rows = 3;

// 间距

CGFloat margin = (self.bounds.size.width - cols * w)/(cols + 1);

// 设置frame

for (NSInteger i = 0;  i < count; i ++)

{

UIButton *btn = (UIButton *)self.subviews[i];

// 当前行

NSInteger row = i / rows;

// 当前列

NSInteger col = i % cols;

// x

x = margin + col * (margin + w);

// y

y = row * (margin + h);

btn.frame = CGRectMake(x, y, w, h);

}

}

定义一个可变数组用来保存选中按钮

@property (nonatomic,strong) NSMutableArray *selectedBtn;

- (NSMutableArray *)selectedBtn

{

if (_selectedBtn == nil) {

_selectedBtn = [NSMutableArray array];

}

return  _selectedBtn;

}

实现滑动手势方法 

- (IBAction)pan:(UIPanGestureRecognizer *)sender {

//    NSLog(@"pan");

// 获取触摸点

_curP = [sender locationInView:self];

// 遍历按钮数组

for (UIButton *btn in self.subviews) {

// 判断点是否包含在按钮中

if (CGRectContainsPoint(btn.frame, _curP) && !btn.selected ) {

btn.selected = YES;

[self.selectedBtn addObject:btn];

}

}

// 重绘

[self setNeedsDisplay];

// 恢复原状

if (sender.state == UIGestureRecognizerStateEnded ) {

// 保存密码

NSMutableString *str = [NSMutableStringstring];

for (UIButton *btn in self.selectedBtn) {

[ str appendFormat:@"%ld",btn.tag ];

}

NSLog(@"%@",str);

// 删除选中状态

[self.selectedBtn makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];

// 情况选中数组

[self.selectedBtn removeAllObjects];

}

}

然后在drawRect中进行连线

- (void)drawRect:(CGRect)rect

{

// 没有选中按钮,直接退出

if (self.selectedBtn.count == 0) {

return;

}

// 把所有选中的按钮连线

NSInteger count = self.selectedBtn.count;

UIBezierPath *path = [UIBezierPathbezierPath];

// 遍历选中按钮数组,对按钮连线

for (int i = 0 ; i < count ; i ++)  {

UIButton *btn = self.selectedBtn[i];

if (i == 0) {

// 设置起点

[path moveToPoint:btn.center];

}else

{

[path addLineToPoint:btn.center];

}

}

// 连接到当前点

[path addLineToPoint:_curP];

// 设置连线样式

[[UIColorgreenColor] set];

path.lineWidth = 10;

path.lineJoinStyle = kCGLineJoinRound;

[path stroke];

}

5、画板

5.1、通过自动布局搭建界面

5.2、在自定义view中得实现

使用滑动手势进行画线

自定义一个继承自UIBezierPath 的类,用来改变线条的颜色,只需添加一个属性即可

#import <UIKit/UIKit.h>

@interface drawPath : UIBezierPath

@property (nonatomic,strong) UIColor *lineColor;

@end

自定义一个view封装画板的操作 DrawView

#import <UIKit/UIKit.h>

@classdrawPath;

@interface DrawView : UIView

@property (nonatomic, strong) UIColor *lineColor; // 线条颜色

@property (nonatomic,assign) CGFloat lineWidth; // 线条宽度

@property (nonatomic,strong) UIImage *image; // 保存加载的图片

- (void)eraseScreen; // 清屏

- (void)undo; // 撤销

@end

类扩展中添加两个属性

#import "DrawView.h"

#import "drawPath.h"

@interfaceDrawView ()

@property (nonatomic,strong) drawPath *path; // 绘图路径

@property (nonatomic,strong) NSMutableArray *drawLines; // 路径数组

@end

// 数组懒加载

- (NSMutableArray *)drawLines

{

if (_drawLines == nil) {

_drawLines = [NSMutableArray array];

}

return  _drawLines;

}

初始化方法

- (void)setUp

{

// 设置手势

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

[selfaddGestureRecognizer:pan];

_lineColor = [UIColor blackColor];

_lineWidth = 1;

}

手势实现

- (void)pan:(UIPanGestureRecognizer *)pan

{

// 获取当前点

CGPoint curPoint = [pan locationInView:self];

if (pan.state == UIGestureRecognizerStateBegan)

{

// 设置起点

_path = [[drawPath alloc] init];

_path.lineColor = _lineColor;

_path.lineWidth = _lineWidth;

[_path moveToPoint:curPoint];

// 保存路径

[self.drawLines addObject:_path];

}

// 绘制

[_path addLineToPoint:curPoint];

// 重绘

[self setNeedsDisplay];

}

重写的构造方法

// xib调用

- (void)awakeFromNib

{

[self setUp];

}

// 代码调用

- (instancetype)initWithFrame:(CGRect)frame

{

if (self = [super initWithFrame:frame]) {

[self setUp];

}

returnself;

}

在drawRect 绘制图片

// 清空屏幕

- (void)drawRect:(CGRect)rect

{

for (drawPath *path  in self.drawLines) {

// 判断是不是图片

if ([path isKindOfClass:[UIImage class]]) {

// 绘制图片

UIImage *image = (UIImage *)path;

[image drawInRect:rect];

}

// 不是图片就画线

else

{

[path.lineColor set];

[path stroke];

}

}

}

 其他方法实现

// 清屏

- (void)eraseScreen

{

[self.drawLines removeAllObjects];

[self setNeedsDisplay];

}

// 撤销

- (void)undo

{

[self.drawLines removeLastObject];

[self setNeedsDisplay];

}

// setter 方法,传入照片时进行刷新

- (void)setImage:(UIImage *)image

{

_image = image;

// 添加图片到绘图数组

[self.drawLinesaddObject:_image];

[selfsetNeedsDisplay];

}

5.3、在控制器中实现

添加两个属性,imageView位于DrawView下面

@property (nonatomic,strong) IBOutlet DrawView *drawView; // 绘图面板

@property (weak, nonatomic) IBOutlet UIImageView *imageView; // 加载的图片显示面板

工具栏:通过拖线的方式创建一个方法

// 清屏

- (IBAction)eraseScreen:(UIBarButtonItem *)sender {

[_drawView eraseScreen];

}

// 撤销

- (IBAction)undo:(id)sender {

[_drawView undo];

}

// 橡皮擦

- (IBAction)eraser:(UIBarButtonItem *)sender {

if ([sender.title isEqualToString:@"橡皮擦"]) {

sender.title  = @"绘图";

_drawView.lineColor = [UIColor whiteColor];

_drawView.lineWidth = 5;

}

else if ([sender.title isEqualToString:@"绘图"]) {

sender.title  = @"橡皮擦";

_drawView.lineColor = [UIColor blackColor];

_drawView.lineWidth = 1;

}

}

// 保存图片到相册

- (IBAction)save:(id)sender {

// 开启上下文

UIGraphicsBeginImageContextWithOptions(self.drawView.bounds.size, NO, 0);

// 获取上下文

CGContextRef ref = UIGraphicsGetCurrentContext();

// 渲染控制器到上下文

[self.drawView.layerrenderInContext:ref];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

// 关闭上下文

UIGraphicsEndImageContext();

// 保存画板的内容放入相册

// image:写入的图片

// completionTarget图片保存监听者

// 注意:以后写入相册方法中,想要监听图片有没有保存完成,保存完成的方法不能随意乱写,必须传入这个方法didFinishSavingWithError

UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

// 保存到桌面

//    NSData *data = UIImagePNGRepresentation(image);

//    [data writeToFile:@"/Users/song/Desktop/sss.png" atomically:YES];

}

// 监听保存完成,必须实现这个方法

- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo

{

NSLog(@"图片保存成功");

}

加载图片:图片控制器

// 从相册加载一张图片

- (IBAction)photo:(id)sender {

// 初始化图片控制器

UIImagePickerController *pick = [[UIImagePickerController alloc] init];

// 设置路径

// 设置选择控制器的来源

// UIImagePickerControllerSourceTypePhotoLibrary 相册集

// UIImagePickerControllerSourceTypeSavedPhotosAlbum:照片库

pick.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;

// 设置代理

pick.delegate = self;

// modal 方式弹出图片控制器

[selfpresentViewController:pick animated:YEScompletion:nil];

}

// 图片代理

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

{

// 获取选中的图片

UIImage *image = info[@"UIImagePickerControllerOriginalImage"];

NSLog(@"%@",image);

self.imageView.alpha = 1; // 可见

self.imageView.userInteractionEnabled = YES; // 设置交互

self.imageView.image = image;

[self addGestures]; // 添加手势

// 退出控制器

[self dismissViewControllerAnimated:YES completion: nil];

}

添加各种手势

- (void)addGestures

{

// 滑动

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

pan.delegate = self;

[self.imageViewaddGestureRecognizer:pan];

// 旋转

UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];

rotate.delegate = self;

[self.imageViewaddGestureRecognizer:rotate];

// 捏合

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];

pinch.delegate = self;

[self.imageViewaddGestureRecognizer:pinch];

// 长按

UILongPressGestureRecognizer *lPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(lPress:)];

[self.imageViewaddGestureRecognizer:lPress];

// 点按

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];

[self.imageViewaddGestureRecognizer:tap];

}

// 同一时刻运行响应多个手势

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

{

return YES;

}

- (void)pan:(UIPanGestureRecognizer *)pan

{

CGPoint curP = [pan translationInView:self.imageView];

self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, curP.x, curP.y);

// 复位

[pan setTranslation:CGPointZeroinView:self.imageView];

}

- (void)pinch:(UIPinchGestureRecognizer *)pinch

{

CGFloat scale = pinch.scale;

self.imageView.transform = CGAffineTransformScale(self.imageView.transform, scale, scale);

// 复位

pinch.scale = 1;

}

- (void)tap:(UITapGestureRecognizer *)tap

{

}

- (void)lPress:(UILongPressGestureRecognizer *)lPress

{

// 截取图片到绘图面板

if (lPress.state == UIGestureRecognizerStateBegan)  {

[UIViewanimateWithDuration:0.25animations:^{

self.imageView.alpha = 0.5;

} completion:^(BOOL finished) {

[UIViewanimateWithDuration:0.25animations:^{

self.imageView.alpha = 1;

} completion:^(BOOL finished) {

// 截屏,使用之前定义的分类,包含头文件即可使用

UIImage *image = [UIImage imageWithSnipView:self.drawView];

self.imageView.alpha = 0;

_drawView.image = image; // 显示图片到绘图面板

}];

}];

}

}

- (void)rotate:(UIRotationGestureRecognizer *)rotate

{

CGFloat rotation = rotate.rotation;

self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation);

// 复位

rotate.rotation = 0;

}

线条颜色和宽度设置

- (IBAction)colorChange:(UIButton *)sender {

_drawView.lineColor = sender.backgroundColor;

}

- (IBAction)valueChange:(UISlider *)sender {

_drawView.lineWidth = sender.value * 10;

}

效果

iOS笔记053- Quartz2D-练习的更多相关文章

  1. 荼菜的iOS笔记--UIView的几个Block动画

    前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...

  2. 【原】iOS学习之Quartz2D(1)

    什么是Quartz2D 1.Quartz 2D 是一个二维绘图引擎,同时支持iOS和Mac系统 2.Quartz 2D 能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成 ...

  3. iOS开发之Quartz2D详解

    1. 什么是Quartz2D? Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片( ...

  4. IOS笔记 1

    < ![CDATA[ 笔记 UIWindows 与UIView的关系iOS的坐标系统视图层次结构视图坐标(Frame和Bounds区别)UIView的常用属性和方法坐标系统的变换UIView内容 ...

  5. iOS开发之Quartz2D

    1.         Quartz2D概述及作用 Quartz2D的API是纯C语言的,Quartz2D的API来自于Core Graphics框架. 数据类型和函数基本都以CG作为前缀,比如: CG ...

  6. 【转】iOS笔记-自定义控件(OC)

    原文网址:http://www.jianshu.com/p/f23862eb7b8a 导读: iOS开发中,很多时候系统提供的控件并不能很好的满足我们的需求,因此,自定义控件便成为搭建UI界面中必不可 ...

  7. iOS笔记———数据存储

    应用沙盒:应用文件系统的根目录,每个应用都有独自的沙盒相互:在xcode中可以用NSHomeDirectory()函数,打印当前应用的沙盒根路径. 应用程序包:包含了所有资源文件和执行文件; * Do ...

  8. IOS 绘图教程Quartz2D

    http://www.cocoachina.com/industry/20140115/7703.html http://www.cnblogs.com/wendingding/p/3803020.h ...

  9. Xamarin开发IOS笔记:切换输入法时输入框被遮住

    在进行IOS开发的过程中,出现类似微信朋友圈的交互界面,当用户遇到感兴趣的内容可以进行评论.为了方便评论输入,当出现评论输入框的时候自动将评论输入框移动至键盘的上方,这样方便边输入边查看. 当用户隐藏 ...

  10. 【IOS笔记】Delegation

    Delegation Delegation is a simple and powerful pattern in which one object in a program acts on beha ...

随机推荐

  1. 并查集,是否成树,Poj(1308)

    思路: 对于每一条新的边的两个端点,是否是属于一颗树,要是的话,就不是一颗树.否则,就合并. 这里要注意的是,不能是森林,我这里WA了两次了.只不过在最后,查看每个节点的祖先是否是同一个就可以了. # ...

  2. 探索性数据分析EDA综述

    目录 1. 数据探索的步骤和准备 2. 缺失值处理 为什么需要处理缺失值 Why data has missing values? 缺失值处理的技术 3. 异常值检测和处理 What is an ou ...

  3. Mac安装protobuf 流程

    下载 https://github.com/google/protobuf/releases 找到对应版本下载 编译 cd protobuf./autogen.sh./configuremake 安装 ...

  4. Python 爬虫的工具列表

    这个列表包含与网页抓取和数据处理的Python库 网络 通用 urllib -网络库(stdlib). requests -网络库. grab - 网络库(基于pycurl). pycurl - 网络 ...

  5. printf、sprintf与fprintf 的用法区分

    原文链接 1: fprintf()#include <stdio.h> int fprintf( FILE *stream, const char *format, ... );fprin ...

  6. Mathematica 讲座

    Mathematica 讲座笔记本 [下载] 第一章 Mathematica 简介 [观看] [下载] 第二章 Mathematica 界面和编程语言 [观看] [下载] 第三章 符号运算 [观看] ...

  7. C#流程控制语句

    C#流程控制语句 一.选择语句 当程序中需要进行两个或两个以上的选择时,可以根据条件的判断来选择将要执行的一组语句. ?if语句 ?switch语句 二.循环语句 循环语句是对一个程序模块进行的重复操 ...

  8. HTML中行内元素和块级元素的区别及转换

    区别可以去找 “html文档流”相关的资料去学习,最主要的区别就是元素是占据一行还是挤在一行 转换的方式是用css的display属性 display:block; /*转换为块级*/display: ...

  9. JS常见内置对象和方法

    JS中常用的内置对象:Array对象.Date对象.正则表达式对象.string对象.Global对象  Array对象中常用方法: concat() 表示把几个数组合并成一个数组join()   设 ...

  10. LVM(扩展)

    LVM(扩展)======================== [root@aminglinux newdir]# fdisk -l /dev/sdb 磁盘 /dev/sdb:10.7 GB, 107 ...