首页
网站首页
公司简介
资讯中心
推荐内容
返回顶部
圆形进度条的绘制,自定义相机及视频录制界面
发布时间:2020-04-15 14:55
浏览次数:

经过是指程序在其内部存款和储蓄器地址的一回运营活动,种种进度之间是单身的,且各类进程都在其专项使用且受保证的内部存储器空间运转。

这段时间在同盟社没什么职分,看项目里面有二个模拟Wechat生活圈的秒拍分界面,认为挺风趣的,于是商讨了一晃AVFoundation,在此记录方今学习的体验,大家一块儿调换。

代码块Block是苹果在iOS4最初引进的对C语言的强大,用来完成匿名函数的特点,Block是一种特有的数据类型,其得以健康定义变量、作为参数、作为再次来到值,特殊地,Block还足以保留一段代码,在需求的时候调用,近日Block已经分布应用于iOS开拓中。Block实际上是OC语言对闭包的落到实处,是包罗自动变量值的无名氏函数。Block不仅能够定义在函数内部也得以定义在函数外界。唯有在调用block的时候,block{}内的代码才会实行。

做iOS开垦也可以有非常短一段时间了,在此段日子里也一向还没怎么写过怎么样事物,越来越多的是在看别人的博客,学习东西,前几天闲来无事(其实越多的是不想看东西了),于是决定自个儿写一篇小说,一贯以为简书的界面很为难,况且平时更多的是在简书上看博客,便决定在这里上边写本身的篇章,记录本人在付出上相见的难题及缓和方案,借使有哪些白玉微瑕还希望各位指正,废话十分的少说,上面初始正文。这一次要说的是绘制圆形进程条,这两天再做一个临近网盘的作用,须要对网盘的公文进行上传、下载作用,在上传只怕下载的历程中要显示文件的进程,当文件上传恐怕下载实现的时候,那个速度要从上传也许下载列表里面移除,因为对绘图一直内什么斟酌(简单的绘图比如画个三角形啊,矩形啊什么的照旧会的),但是因为这些进度条涉及到未到位颜色,实现颜色什么的,此时也还没怎么思路,于是自个儿研商了弹指间绘制,又下载了多少个DEMO,结合了弹指间住家的代码,终于现了需要,话超级少少,上代码

进程想要实行职责必需有线程,每一个进度必定要有一条线程,线程是进度的为主进行单元,线程重视于经过而现成,三个历程之中能够有四个线程

诚如只要UI和UE在安插时只必要效果与利益,对相机界面没什么要求的话,个人感觉调用系统相机(UIImagePickerController)就能够满足大家的急需举个例子照相也许录像摄像,不过寻思分界面美观性,有的时候候就需求大家自定义拍戏界面,那时系统相机已经满足不断大家的供给,跟多的是要跟AVFoundation打交道,这中间推抢了一晃系统底层的事物,时有时无商量了几天只是出于内容实在太多,所以在此只记录基本的照相以致录制录像功效,如若有别的需要还亟需大家去查看资料(技士的悲催生活啊),下边步向正题。

闭包就是四个函数,大概三个指向性函数的指针,加上这一个函数履行的非局地变量。闭包允许四个函数访谈证明该函数运营上下文中的变量,以致足以访谈分裂运行上文中的变量。

图片 1显示屏快速照相二零一五-05-31 20.38.34.png

从技巧角度来看,三个线程正是三个急需管住实践代码的内核级和应用级数据构造组合。内核级构造推推搡搡调整线程事件,并抢占式调治一个线程到可用的内核之上。应用级构造包含用于存款和储蓄函数调用的调用仓库和应用程序须要管住和操作线程属性和境况的组织。

在跟AVFoundation打交道的时候有几点是亟需超前认知的,认识这几点作者觉着完毕基本的拍照以致录像功用基本上就没难题了:

 int  = ^{return num*num;};
#import "WangPanCircleProgressView.h"@implementation WangPanCircleProgressView- initWithFrame:frame{ self = [super initWithFrame:frame]; if  { self.backgroundColor = [UIColor clearColor]; _percent = 0; _width = 2; } return self;}- setPercent:percent{ _percent = percent; [self setNeedsDisplay];}- drawRect:rect{ [self addCircleBackgroundColor]; [self drawArc]; [self addCenterBack]; [self addCenterLabel];}//设置圆的背景色及画圆-addCircleBackgroundColor{ CGColorRef color = (_circleBackgroundColor == nil) ? [UIColor grayColor].CGColor : _circleBackgroundColor.CGColor; CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGSize viewSize = self.bounds.size; CGPoint center = CGPointMake(viewSize.width/2, viewSize.height/2); //画圆 CGFloat radius = viewSize.width/2; CGContextBeginPath(contextRef); CGContextMoveToPoint(contextRef, center.x, center.y); CGContextAddArc(contextRef, center.x, center.y, radius, 0, 2*M_PI, 0); CGContextSetFillColorWithColor(contextRef, color); CGContextFillPath(contextRef);}//画下载的圆弧- drawArc{ if (_percent == 0 || _percent > 1) { return; } if (_percent == 1) { CGColorRef color = (_circleUnFinishColr == nil) ? [UIColor redColor].CGColor : _circleUnFinishColr.CGColor; CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGSize viewSize = self.bounds.size; CGPoint center = CGPointMake(viewSize.width/2, viewSize.height/2); //画圆弧 CGFloat radius = viewSize.width/2; CGContextBeginPath(contextRef); CGContextMoveToPoint(contextRef, center.x, center.y); CGContextAddArc(contextRef, center.x, center.y, radius, 0, 2*M_PI, 0); CGContextSetFillColorWithColor(contextRef, color); CGContextFillPath(contextRef); } else { float endAngle =  * _percent - M_PI_2; CGColorRef color = (_circleUnFinishColr == nil) ? [UIColor redColor].CGColor : _circleUnFinishColr.CGColor; CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGSize viewSize = self.bounds.size; CGPoint center = CGPointMake(viewSize.width/2, viewSize.height/2); //画圆弧 CGFloat radius = viewSize.width/2; CGContextBeginPath(contextRef); CGContextMoveToPoint(contextRef, center.x, center.y); CGContextAddArc(contextRef, center.x, center.y, radius, -0.5*M_PI, endAngle, 0); CGContextSetFillColorWithColor(contextRef, color); CGContextFillPath(contextRef); } }//画中心的圆-addCenterBack{ float width = (_width == 0) ? 5 : _width; CGColorRef color = (_centerColor == nil)?[UIColor whiteColor].CGColor : _centerColor.CGColor; CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGSize viewSize = self.bounds.size; CGPoint center = CGPointMake(viewSize.width/2, viewSize.height/2); //画圆弧 CGFloat radius = viewSize.width/2 - width; CGContextBeginPath(contextRef); CGContextMoveToPoint(contextRef, center.x, center.y); CGContextAddArc(contextRef, center.x, center.y, radius, 0, 2*M_PI, 0); CGContextSetFillColorWithColor(contextRef, color); CGContextFillPath(contextRef);}//画中心的标签- addCenterLabel{ NSString *percent = @""; float fontSize = 9 ; UIColor *centerLabelColor = [UIColor grayColor]; if(_percent == 1) { percent = @"100%"; fontSize = 8; centerLabelColor = (_centerColor == nil)?[UIColor grayColor] : _circleUnFinishColr; [self performSelector:@selector(hiddenView) withObject:nil afterDelay:0.5]; } else if (_percent<1 && _percent >= 0) { centerLabelColor = (_centerColor == nil)?[UIColor grayColor] : _circleUnFinishColr; percent = [NSString stringWithFormat:@"%.0f%%",_percent*100]; } CGSize viewSize = self.bounds.size; NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc]init]; paragraph.alignment = NSTextAlignmentCenter; paragraph.alignment = NSTextAlignmentCenter; NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont boldSystemFontOfSize:fontSize],NSFontAttributeName ,centerLabelColor,NSForegroundColorAttributeName,[UIColor clearColor],NSBackgroundColorAttributeName,paragraph,NSParagraphStyleAttributeName,nil]; [percent drawInRect:CGRectMake(5, (viewSize.height-fontSize)/2, viewSize.width-10, fontSize) withAttributes:attributes]; }-hiddenView{ self.hidden = YES;}@end

三十二线程的优势:八线程可以增加应用程序的感知响应四十十六线程能够增加应用程序在多核系统上的实时品质。

 AVCaptureSession:媒体捕获会话,负责把捕获的音视频数据输出到输出设备中,一个AVCaptureSession可以有多个输入输出(前面的是比较专业的说法,然并卵,个人理解这其实相当于一个会话,连接了音频之间的输入和输出,即从你开始拍照或者录制视频到最后出现照片或者视频,整个过程之间的数据流是由它管理的) AVCaptureDevice:输入设备,包括麦克风、摄像头,通过该对象可以设置物理设备的一些属性(例如相机聚焦、白平衡等) AVCaptureDeviceInput:设备输入数据管理对象,可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,该对象将会被添加到AVCaptureSession中管理。(即一个输入设备对应一个输入管理对象,然后把它加入会话中) AVCaptureOutput:输出数据管理对象,用于接收各类输出数据,但是通常我们不直接用它更多的使用它的子类AVCaptureStillImageOutput、AVCaptureMovieFileOutput(相对应的它也是要加入会话的) AVCaptureVideoPreviewLayer:相机拍摄预览图层,是CALayer的子类,使用该对象可以实时查看拍照或视频录制效果,创建该对象需要指定对应的AVCaptureSession对象(它可以理解为拍照或者录制视频时显示的层)。

int 代表回到类型 ^代表的那是多个block

在代码里当最后圆环进程为1即百分之百的时候让它隐敝了,那是笔者那方面包车型大巴必要,借使不须要能够将艺术注释,作者觉的这一点代码基本兰秋经足以满意半数以上必要了,如若有不适当之处,各位可以协调再说修正,第三遍写,有怎么样不佳之处还望各位见谅

四线程的劣点:扩大代码复杂性,带给大气的开支每三个线程必要和其他线程和睦其行事,以免范损坏应用程序的气象音信。十二线程访谈其分享的内部存款和储蓄器空间大概损坏其数据构造。

好了,上面是大家先行要通晓的,理解它们那么上边将更加好的敞亮(当然你不打听也没涉及,也许自个儿表达的非常不足明亮,不过作者拼命了),最直观的照旧先来看代码吧,上边包车型大巴是拍片的代码,先看一下定义的习性吧

myBlock代表block的名字 代表参数类型

二个run loop是用来在线程上管管事人件异步达到的底蕴设备。一个run loop为线程监测一个或四个事件源。当事件达到的时候,系统提示线程并调解事件到run loop,然后分配给钦命程序。若无事件现身和筹算管理,run loop把线程置于休眠状态

@property(nonatomic,strong)AVCaptureSession *session;@property(nonatomic,strong)AVCaptureDevice *device;@property(nonatomic,strong)AVCaptureDeviceInput *input;@property(nonatomic,strong)AVCaptureStillImageOutput *imageOutput;@property(nonatomic,strong)AVCaptureVideoPreviewLayer *videoLayer;@property(nonatomic,strong)UIImageView *focusImage;//聚焦框

表示形参的门类及名字

在iOS中,线程有两连串型,分别为Joinable和Detach,Joinable类型的线程能够被其它线程回笼财富和截至。若是叁个Joinable的线程与主线程结合,那么当主线程甘休而该二级线程还并未有终结的时候,主线程会被封堵等待该二级线程,当二级线程甘休后由主线程回笼其占用财富并将其倒闭。如果在主线程尚未终止而该二级线程截至了,那么它不光不会停业,而且资源也不会被系统回笼,只是等待主线程管理。而detach线程则刚刚相反,会自动结束关闭线程况且由系统回笼财富。

下边是初叶化的代码

在定义block的时候一定毫无忘记在结尾加上分号

队列只是承受职责的调节,而不担任任务的施行,职务是在线程中施行的。队列固守先进先出原则,排在前边的职务最早实施

- viewDidLoad { [super viewDidLoad]; //添加聚焦框 self.focusImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 60, 60)]; self.focusImage.center = self.centerView.center; [self.focusImage setImage:[UIImage imageNamed:@"边框"]]; [self.centerView addSubview:_focusImage]; self.centerView.layer.masksToBounds = YES; //加上这句话,主要是为了当聚焦时聚焦框超出centerView裁剪聚焦框 //建立会话 _session = [[AVCaptureSession alloc]init]; //设置分辨率 if ([self.session canSetSessionPreset:AVCaptureSessionPreset1280x720]) { [self.session setSessionPreset:AVCaptureSessionPreset1280x720]; } //取得设备 NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *devide in deviceArray) { if (devide.position == AVCaptureDevicePositionBack) { NSLog(@"取得的是后置摄像头"); _device = devide; } if (devide.position == AVCaptureDevicePositionFront) { NSLog(@"前置摄像头有但是没取"); } } NSError *error = nil; //建立输入设备 _input = [[AVCaptureDeviceInput alloc]initWithDevice:_device error:&error]; //将输入设备添加到回话 if ([_session canAddInput:_input]) { [_session addInput:_input]; } //建立输出设备 _imageOutput = [[AVCaptureStillImageOutput alloc]init]; //将输入设备加入会话 if ([_session canAddOutput:_imageOutput]) { [_session addOutput:_imageOutput]; } //建立照相预览层 _videoLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:_session]; _videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; CALayer *layer = self.centerView.layer; _videoLayer.frame = layer.bounds; _videoLayer.masksToBounds = YES; [layer insertSublayer:_videoLayer below:_focusImage.layer];//将拍摄层插入到聚焦框下面不然聚焦框不显示 [_session startRunning]; [self addGestureTap];//添加手势用于聚焦 [self addNotificationToCaptureDevide:_device];//给设备添加通知}

block是二个对象,内部是一个构造体,在开立block 的时候就把它的指针传给了block,所以能够向来调用block块

任务依据顺序被调整,前多个职责不执行完成,队列不会调整

当拍片按键点击时:

不过为了利用block方便,日常在定义block的时候会用typedef简化block如:typedef void ;

友情链接: 网站地图
Copyright © 2015-2019 http://www.nflfreepicks.net. 新葡萄京娱乐场网址有限公司 版权所有