iOS开发Quzrtz2D:十一:图片截屏以及图片擦除
一:图片截屏:截取的是控制器的view
- #import "ViewController.h"
- @interface ViewController ()
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- }
- -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- //把控制器的View生成一张图片
- //1.开启一个位图上下文(跟当前控制器View一样大小的尺寸)
- /**
- *开启一个位图上下文:1:第一个参数为上下文的size 2:第二个参数为不透明,传no,代表透明 3:第三个分辨率,传0系统会默认根据根据分辨率去设置
- */
- UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, );
- /**
- * 1:此时需要获取当前的上下文,类型为CGContextRef 2:view上之所以能显示各种UI控件,是因为是系统将这些UI控件渲染到了view的layer的图层上,才能显示出来
- 2:把view绘制到上下文上,必须将view的layer渲染到上下文,像是图片或是一些形状直接画到上下文就可以了
- *
- */
- //把把控制器的View绘制到上下文当中.
- //2.想要把UIView上面的东西给绘制到上下文当中,必须得要使用渲染的方式.
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- [self.view.layer renderInContext:ctx];
- //[self.view.layer drawInContext:ctx];
- //3.从上下文当中生成一张图片
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- //4.关闭上下文
- UIGraphicsEndImageContext();
- //把生成的图片写入到桌面(文件方式进行传输:二进制流NSData)
- //把图片转成二进制流NSData
- //NSData *data = UIImageJPEGRepresentation(newImage, 1);
- /**
- * 1:将图片写入文件里:需要将图片首先转化为二进制流的形式NSData,才可以writeToFile写入文件,此方法支持写入文件的类型为,NSStrig,NSDictrary,NSArray,BOOL,NSDate,NSData,NSNumber,数据或是字典中装入的对象也必须是上述类型,否则会报错。
- * 2:将图片转化为二进制流,用UIImagePNGRepresentation,UIImageJPEGRepresentation,其中png为最高清的图片,JPEG有压缩比例,比例越大越不清晰,返回值都是NSData
- */
- NSData *data = UIImagePNGRepresentation(newImage);
- [data writeToFile:@"/Users/cqb/Desktop/newImage.png" atomically:YES];
- }
- @end
截屏效果实现具体思路为:把UIView的东西绘制图片上下文当中,生成一张新的图片.
注意:UIView上的东西是不能直接画到上下文当中的.
UIView之所以能够显示是因为内部的一个层(layer),所以我要把层上的东西渲染到UIView上面的.
怎样把图层当中的内容渲染到上下文当中?
直接调用layer的renderInContext:方法
renderInContext:带有一个参数, 就是要把图层上的内容渲染到哪个上下文.
截屏具体实现代码为:
1.开启一个图片上下文
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
获取当前的上下文.
CGContextRef ctx = UIGraphicsGetCurrentContext();
2.把控制器View的内容绘制上下文当中.
[self.view.layer renderInContext:ctx];
3.从上下文当中取出图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
4.关闭上下文.
UIGraphicsEndImageContext();
二:图片截屏:效果如图:
- #import "ViewController.h"
- @interface ViewController ()
- @property (weak, nonatomic) IBOutlet UIImageView *imageV;
- //开始时手指的点
- /** <#注释#> */
- @property (nonatomic, assign) CGPoint startP;
- /** <#注释#> */
- @property (nonatomic, weak) UIView *coverV;
- @end
- @implementation ViewController
- /**
- * 懒加载coverV
- * 1.能够保证超始至终只有一份
- * 2.什么时候用到什么时候才去加载
- */
- -(UIView *)coverV {
- if (_coverV == nil) {
- //添加一个UIView
- UIView *coverV = [[UIView alloc] init];
- coverV.backgroundColor = [UIColor blackColor];
- coverV.alpha = 0.7;
- _coverV = coverV;
- [self.view addSubview:coverV];
- }
- return _coverV;
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
- /*
- 1:按钮的点击事件或是手势事件,都需要开启用户的交互权限
- 2:不能接受点击事件的三种情况:1:没有开启用户交互权限userInteractionEnabled = NO 2:控件隐藏,父控件隐藏则子控件也会隐藏 2:透明度在0.0 - 0.01,父控件透明度在此范围内,则子控件也在此范围内,均不能接受点击事件
- */
- self.imageV.userInteractionEnabled = YES;
- }
- - (IBAction)pan:(UIPanGestureRecognizer *)pan {
- //判断手势的状态
- CGPoint curP = [pan locationInView:self.imageV];//时刻更新的拖拽点
- if(pan.state == UIGestureRecognizerStateBegan) {//开始拖拽
- self.startP = curP;//记录刚开始点击的点
- } else if(pan.state == UIGestureRecognizerStateChanged) {//正在拖拽
- //求出在拖拽平移时,cover矩形框的frame,原点为刚开始拖拽的点
- CGFloat x = self.startP.x;
- CGFloat y = self.startP.y;
- CGFloat w = curP.x - self.startP.x;
- CGFloat h = curP.y - self.startP.y;
- CGRect rect = CGRectMake(x, y, w, h);
- //添加一个UIView:采用懒加载:1:保证只加载一次,且不用管代码的执行顺序,此处若不用懒加载,则每次拖拽平移点改变的时候,都会重新初始化一个新对象加在self.view(若是只有一个对象则多次addSubview,则该控件只会添加一次)
- self.coverV.frame = rect;
- } else if (pan.state == UIGestureRecognizerStateEnded) {//拖拽结束
- //把超过coverV的frame以外的内容裁剪掉
- //生成了一张图片,把原来的图片给替换掉.
- UIGraphicsBeginImageContextWithOptions(self.imageV.bounds.size, NO, );
- //把ImageV绘制到上下文之前,设置一个裁剪区域
- UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:self.coverV.frame];
- [clipPath addClip];
- /**
- *1:UIImageView也是继承UIView,所以将UIImageView添加到上下文也必须得将UIImageView的layer渲染到上下文,所以只要是UIview或是继承UIView的控件添加到上下文中,都需要将其layer渲染到上下文: [self.imageV.layer renderInContext:ctx]
- *2:一般都是先开启上下文,绘制裁剪路径,将UIImageView的layer绘制到上下文,得到新图片,关闭上下文
- */
- //把当前的ImageView渲染到上下文当中
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- [self.imageV.layer renderInContext:ctx];
- //.从上下文当中生成 一张图片
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- //关闭上下文
- UIGraphicsEndImageContext();
- [self.coverV removeFromSuperview];
- self.imageV.image = newImage;
- }
- }
- @end
图片截屏实现思路.
手指在屏幕上移动的时
添加一个半透明的UIView,
然后开启一个上下文把UIView的frame设置成裁剪区域.把图片显示的图片绘制到上下文当中,生成一张新的图片
再把生成的图片再赋值给原来的UImageView.
具体实现步骤:
1.给图片添加一个手势,监听手指在图片上的拖动,添加手势时要注意,UIImageView默认是不接事件的.
要把它设置成能够接收事件
2.监听手指的移动.手指移动的时候添加一个UIView,
x,y就是起始点,也就是当前手指开始的点.
width即是x轴的偏移量,
高度即是Y轴的偏移量.
UIView的尺寸位置为CGrect(x,y,witdth,height);
计算代码为:
CGFloat offSetX = curP.x - self.beginP.x;
CGFloat offsetY = curP.y - self.beginP.y;
CGRect rect = CGRectMake(self.beginP.x, self.beginP.y, offSetX, offsetY);
UIView之需要添加一次,所以给UIView设置成懒加载的形式,
保证之有一个.每次移动的时候,只是修改UIView的frame.
3.开启一个图片上下文,图片上下文的大小为原始图片的尺寸大小.使得整个屏幕都能够截屏.
利用UIBezierPath设置一个矩形的裁剪区域.
然后把这个路径设置为裁剪区域.
把路径设为裁剪区域的方法为:
[path addClip];
4.把图片绘制到图片上下文当中
由于是一个UIImageView上面的图片,所以也得需要渲染到上下文当中.
要先获取当前的上下文,
把UIImageView的layer渲染到当前的上下文当中.
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.imageV.layer renderInContext:ctx];
5.取出新的图片,重新赋值图片.
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
self.imageV.image = newImage;
6.关闭上下文,移除上面半透明的UIView
UIGraphicsEndImageContext();
[self.coverView removeFromSuperview];
三:图片擦除:效果如图:
- #import "ViewController.h"
- @interface ViewController ()
- @property (weak, nonatomic) IBOutlet UIImageView *imageV;
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- //添加手势
- UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
- [self.imageV addGestureRecognizer:pan];
- }
- - (void)pan:(UIGestureRecognizer *)pan {
- //获取当前手指的点
- CGPoint curP = [pan locationInView:self.imageV];
- //确定擦除区域
- CGFloat rectWH = ;
- CGFloat x = curP.x - rectWH * 0.5;
- CGFloat y = curP.y - rectWH * 0.5;
- CGRect rect = CGRectMake(x, y, rectWH, rectWH);
- //生成一张带有透明擦除区域的图片
- //1.开启图片上下文
- UIGraphicsBeginImageContextWithOptions(self.imageV.bounds.size, NO, );
- //2.把UIImageV内容渲染到当前的上下文当中
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- [self.imageV.layer renderInContext:ctx];
- //3.擦除上下文当中的指定的区域
- CGContextClearRect(ctx, rect);
- //4.从上下文当中取出图片
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- //替换之前ImageView的图片
- self.imageV.image = newImage;
- }
- @end
图片擦除思路.
弄两个不同的图片.上面一张, 下面一张.
添加手势,手指在上面移动,擦除图片.
擦除前要先确定好擦除区域.
假设擦除区域的宽高分别为30.
那点当前的擦除范围应该是通过当前的手指所在的点来确定擦除的范围,位置.
那么当前擦除区域的x应该是等于当前手指的x减去擦除范围的一半,同样,y也是当前手指的y减去高度的一半.
有了擦除区域,要让图片办到擦除的效果,首先要把图片绘制到图片上下文当中, 在图片上下文当中进行擦除.
之后再生成一张新的图片,把新生成的这一张图片设置为上部的图片.那么就可以通过透明的效果,看到下部的图片了.
第一个参数, 要擦除哪一个上下文
第二人参数,要擦除的区域.
CGContextClearRect(ctx, rect);
具体实现代码为:
确定擦除的范围
CGFloat rectWH = 30;
获取手指的当前点.curP
CGPoint curP = [pan locationInView:pan.view];
CGFloat x = curP.x - rectWH * 0.5;
CGFloat y = curP.y - rectWH * 0.5;
CGRect rect = CGRectMake(x, y,rectWH, rectWH);
先把图片绘制到上下文.
UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
获取当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
把上面一张图片绘制到上下文.
[self.imageView.layer renderInContext:ctx];
再绘上下文当中图片进行擦除.
CGContextClearRect(ctx, rect);
生成一张新图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
再把新的图片给重新负值
self.imageView.image = newImage;
关闭上下文.
UIGraphicsEndImageContext();
iOS开发Quzrtz2D:十一:图片截屏以及图片擦除的更多相关文章
- IOS开发-几种截屏方法
IOS开发-几种截屏方法 1. UIGraphicsBeginImageContextWithOptions(pageView.page.bounds.size, YES, zoomSc ...
- iOS开发UI篇—UIScrollView控件实现图片缩放功能
iOS开发UI篇—UIScrollView控件实现图片缩放功能 一.缩放 1.简单说明: 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对 ...
- iOS开发UI篇—UIScrollView控件实现图片轮播
iOS开发UI篇—UIScrollView控件实现图片轮播 一.实现效果 实现图片的自动轮播 二.实现代码 storyboard中布局 代码: #import "YYV ...
- iOS开发之静态库(五)—— 图片、界面xib等资源文件封装到静态框架framework
编译环境:Macbook Air + OS X 10.9.2 + XCode5.1 + iPhone5s(iOS7.0.3) 一.首先将资源文件打包成bundle 由于bundle是静态的,所以可以将 ...
- 【转】 iOS开发UI篇—UIScrollView控件实现图片轮播
原文:http://www.cnblogs.com/wendingding/p/3763527.html iOS开发UI篇—UIScrollView控件实现图片轮播 一.实现效果 实现图片的自动轮播 ...
- iOS开发Quzrtz2D 十:圆形图片的绘制以及加边框圆形图片的绘制
一:圆形图片的绘制 @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageV; @en ...
- Java开发的一个简单截屏工具
//源代码 import java.awt.*;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transfe ...
- iOS开发——UI篇OC篇&不规则排列的图片布局
不规则排列的图片布局 一直在500px上看照片,发照片.以前看它的首页图片展示就只是觉得好看,洋气,也没想过自己在iOS上实现一下.昨天不知怎么的就开始想其中的算法了,现在我把思考的过程在这里贴出来分 ...
- iOS开发之静态库(三)—— 图片、界面xib等资源文件封装到.a静态库
编译环境:Macbook Air + OS X 10.9.2 + XCode5.1 + iPhone5s(iOS7.0.3) 一.首先将资源文件打包成bundle 新建工程:File -> Ne ...
随机推荐
- Oracle APEX 4.2公布RESTful Webservice
Purpose This tutorial covers creating a RESTful Web Service and accessing the Web Service through an ...
- go timer
go timer package main import ( "fmt" "time" ) func debounce(interval time.Durati ...
- 带你走进EJB--EJB和Spring对比(转)
http://blog.csdn.net/jnqqls/article/details/17723417 通过对EJB系列的总结和学习我们已经对EJB有了基本的了解,但是为了更进一步的去深入学习EJB ...
- (转)Tomcat目录结构
首先来了解一下Tomcat5.5的目录结构: /bin:存放windows或Linux平台上启动和关闭Tomcat的脚本文件 /conf:存放Tomcat服务器的各种全局配置文件,其中包括server ...
- sql server还原数据库代码
RESTORE DATABASE ExaminationsystemFROM DISK = 'C:\Users\admin\Desktop\20140324.bak'with replace,MOVE ...
- 【Educational Codeforces Round 35 C】Two Cakes
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 直觉题. 感觉情况会很少. 毕竟间隔太大了.中间肯定有一些数字达不到. 有1肯定可以 2 2 x肯定可以 3 3 3也可以 2 4 ...
- ViewPager (下)-- 利用 Fragment 实现美丽的 页面切换
之前用的ViewPager适用于简单的广告切换,但实现页面间的切换最好是用官方推荐的Fragment来处理. 本人力争做到最简单.最有用,是想以后用到的时候能够方便的拿过来复制就能够了. 效果图: w ...
- 不安装谷歌市场,下载谷歌市场中的APK
不安装谷歌市场,下载谷歌市场中的APK GooglePlayStore 是谷歌官方的的应用市场,有的时候还是需要从谷歌市场下载APK文件.国内的安卓手机厂商都不自带GooglePlay,甚至一些手机& ...
- ubuntu-安装中文拼音输入法
一下内容转载自http://blog.chinaunix.net/uid-24410388-id-3501873.html 自己验证了可用.转载了,已留做日后使用 步骤: step1:安装ibus所需 ...
- 12.模板别名以及auto定义返回值
#include <iostream> #include <array> using namespace std; //定义返回值类型 template<class T1 ...