JXCameraVC.m 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. //
  2. // JXCameraVC.m
  3. // shiku_im
  4. //
  5. // Created by p on 2017/11/6.
  6. // Copyright © 2017年 Reese. All rights reserved.
  7. //
  8. #import "JXCameraVC.h"
  9. #import "GPUImage.h"
  10. #import "GPUImageBeautifyFilter.h"
  11. #import "JXVideoPlayer.h"
  12. #import "UIImage+Color.h"
  13. #import "KKImageEditorViewController.h"
  14. #define kCameraVideoPath [FileInfo getUUIDFileName:@"mp4"]
  15. @interface JXCameraVC () <KKImageEditorDelegate,UINavigationControllerDelegate>
  16. @property (nonatomic, strong) GPUImageStillCamera *stillCamera; // 拍照
  17. @property (nonatomic, strong) GPUImageVideoCamera *videoCamera; // 錄像
  18. @property (nonatomic, strong) GPUImageMovieWriter *movieWriter; // 存錄像
  19. @property (nonatomic, strong) UIButton *photoCaptureButton;
  20. @property (nonatomic, strong) UIImageView *iv;
  21. @property (nonatomic, strong) GPUImageBeautifyFilter *beautifyFilter;
  22. @property (nonatomic, strong) NSArray *filterArray;
  23. @property (nonatomic, strong) GPUImageFilterGroup *filterGroup;
  24. @property (nonatomic, strong) GPUImageCropFilter *cropFilter;
  25. @property (nonatomic, strong) NSMutableArray *photoStyleImages;
  26. @property (nonatomic, strong) UILabel *noticeLabel;
  27. @property (nonatomic, strong) UIImageView *timeBGView;
  28. @property (nonatomic, strong) UILabel *timeLabel;
  29. @property (nonatomic, strong) NSTimer *recordTimer;
  30. @property (nonatomic, assign) NSInteger timerNum;
  31. @property (nonatomic, assign) BOOL isRecording;
  32. @property (nonatomic, strong) UIView *playerView;
  33. @property (nonatomic, strong) JXVideoPlayer *player;
  34. @property (nonatomic, strong) UIButton *beautyBtn;
  35. @property (nonatomic, strong) GPUImageBrightnessFilter *normalFilter;
  36. @property (nonatomic, assign) BOOL isNotPhoto; // 判断[self takePhoto]方法进入拍照还是视频录制
  37. //美颜/滤镜属性
  38. @property (nonatomic, strong) UIView *baseView;
  39. @property (nonatomic, strong) UIView *bigView;
  40. @property (nonatomic, strong) UIScrollView *scrollView;
  41. @property (nonatomic, strong) UIView *bottomControlView;
  42. @property (nonatomic, strong) UIButton *filterBtn;
  43. @property (nonatomic, strong) UIButton *skinCareBtn;
  44. @property (nonatomic, assign) BOOL isCreateFilter;
  45. //// isRecoverHis = YES作用是 当前滤镜调整到正常后,要记录美颜中的磨皮和亮度的历史值
  46. //@property (nonatomic, assign) BOOL isRecoverHis;
  47. @property (nonatomic, strong) UISlider *bilateralSld;
  48. @property (nonatomic, strong) UISlider *brightnessSld;
  49. @property (nonatomic, assign) CGFloat bilHis;
  50. @property (nonatomic, assign) CGFloat briHis;
  51. @property (nonatomic, strong) GPUImageBilateralFilter *bilateralFilter;// 磨皮滤镜
  52. @property (nonatomic, strong) GPUImageBrightnessFilter *brightnessFilter;// 美白滤镜
  53. @property (nonatomic, strong) GPUImageToonFilter *toonfilter;
  54. @property (nonatomic, strong) GPUImageFilter *filter;//滤镜
  55. @end
  56. @implementation JXCameraVC
  57. - (void)viewDidLoad {
  58. [super viewDidLoad];
  59. // Do any additional setup after loading the view.
  60. self.view.backgroundColor = [UIColor whiteColor];
  61. _photoStyleImages = [NSMutableArray array];
  62. _isRecording = NO;
  63. if([self cameraCount]<=0){
  64. [self performSelector:@selector(dismissViewControllerAnimated:completion:) withObject:nil afterDelay:0.5];
  65. // [self dismissViewControllerAnimated:YES completion:nil];
  66. [g_App performSelector:@selector(showAlert:) withObject:Localized(@"JXAlert_NoCenmar") afterDelay:1];
  67. return;
  68. }
  69. // Yes, I know I'm a caveman for doing all this by hand
  70. GPUImageView *primaryView = [[GPUImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  71. primaryView.backgroundColor = [UIColor blackColor];
  72. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(switchSkinCare)];
  73. [primaryView addGestureRecognizer:tap];
  74. // 添加上下两个地方的透明模板
  75. UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, JX_SCREEN_WIDTH, THE_DEVICE_HAVE_HEAD ? 62 : 42)];
  76. UIView *botView = [[UIView alloc] initWithFrame:CGRectMake(0, JX_SCREEN_HEIGHT-90, JX_SCREEN_WIDTH, 90)];
  77. topView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
  78. botView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
  79. [primaryView addSubview:topView];
  80. [primaryView addSubview:botView];
  81. //中间录制按钮
  82. _photoCaptureButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  83. _photoCaptureButton.frame = CGRectMake(round(JX_SCREEN_WIDTH / 2.0 - 50.0 / 2.0), JX_SCREEN_HEIGHT - 70.0, 50.0, 50.0);
  84. [_photoCaptureButton setBackgroundImage:[UIImage imageNamed:_isPhoto ? @"start" : @"start_video"] forState:UIControlStateNormal];
  85. // [_photoCaptureButton addTarget:self action:@selector(singlePress:) forControlEvents:UIControlEventTouchUpInside];
  86. [_photoCaptureButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
  87. [primaryView addSubview:_photoCaptureButton];
  88. UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singlePress:)];
  89. [_photoCaptureButton addGestureRecognizer:singleTap];
  90. UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
  91. longPress.minimumPressDuration = 0.5; //最小长按时间
  92. [_photoCaptureButton addGestureRecognizer:longPress];
  93. UIButton *cancelBtn = [[UIButton alloc] initWithFrame:CGRectMake(15, JX_SCREEN_HEIGHT - 60.0, 30, 30)];
  94. [cancelBtn setImage:[UIImage imageNamed:@"fork"] forState:UIControlStateNormal];
  95. [cancelBtn addTarget:self action:@selector(cancelBtnAction:) forControlEvents:UIControlEventTouchUpInside];
  96. [cancelBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  97. [primaryView addSubview:cancelBtn];
  98. UIButton *switchBtn = [[UIButton alloc] initWithFrame:CGRectMake(JX_SCREEN_WIDTH - 45, JX_SCREEN_HEIGHT - 60.0, 30, 30)];
  99. [switchBtn setImage:[UIImage imageNamed:@"switch_cammer"] forState:UIControlStateNormal];
  100. [switchBtn addTarget:self action:@selector(switchBtnAction:) forControlEvents:UIControlEventTouchUpInside];
  101. [switchBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  102. [primaryView addSubview:switchBtn];
  103. self.view = primaryView;
  104. // GPUImageGaussianBlurFilter * blurFilter = [[GPUImageGaussianBlurFilter alloc] init];
  105. // blurFilter.blurRadiusInPixels = 2.0;
  106. // dispatch_async(dispatch_get_global_queue(0, 0),^{
  107. // // 处理耗时操作的代码块...
  108. if (self.isVideo) {
  109. [self initVideoCamera];
  110. }else if (self.isPhoto) {
  111. [self initPhotoCamera];
  112. }else {
  113. // [self initPhotoCamera];
  114. _stillCamera = [[GPUImageStillCamera alloc] init];
  115. _videoCamera = _stillCamera;
  116. [self initVideoCamera];
  117. }
  118. // });
  119. //必须判定是否有闪光灯,否则如果没有闪光灯会崩溃
  120. if (_stillCamera.inputCamera.hasFlash || _videoCamera.inputCamera.hasFlash) {
  121. UIButton *flashBtn = [[UIButton alloc] initWithFrame:CGRectMake(30, THE_DEVICE_HAVE_HEAD ? 32 : 12, 18, 18)];
  122. [flashBtn setImage:[UIImage imageNamed:@"automatic"] forState:UIControlStateNormal];
  123. [flashBtn addTarget:self action:@selector(flashBtnAction:) forControlEvents:UIControlEventTouchUpInside];
  124. [flashBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  125. [primaryView addSubview:flashBtn];
  126. }
  127. // 显示美颜调整界面
  128. _beautyBtn = [[UIButton alloc] initWithFrame:CGRectMake(JX_SCREEN_WIDTH - 30-18, THE_DEVICE_HAVE_HEAD ? 32 : 12, 18, 18)];
  129. _beautyBtn.selected = NO;
  130. [_beautyBtn setImage:[UIImage imageNamed:@"camra_beauty"] forState:UIControlStateNormal];
  131. [_beautyBtn addTarget:self action:@selector(beautyBtnAction:) forControlEvents:UIControlEventTouchUpInside];
  132. [_beautyBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  133. [primaryView addSubview:_beautyBtn];
  134. // [self addPhotoStyle:primaryView];
  135. _iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, JX_SCREEN_WIDTH, JX_SCREEN_HEIGHT)];
  136. _iv.backgroundColor = [UIColor blackColor];
  137. _iv.contentMode = UIViewContentModeScaleAspectFill;
  138. _iv.userInteractionEnabled = YES;
  139. _iv.hidden = YES;
  140. [primaryView addSubview:_iv];
  141. UIButton *cancelImageBtn = [self createButtonWithFrame:CGRectMake(20, JX_SCREEN_HEIGHT-20-80, 80, 80) image:@"video_return" action:@selector(cancelImageBtnAction:)];
  142. [_iv addSubview:cancelImageBtn];
  143. UIButton *editBtn = [self createButtonWithFrame:CGRectMake(JX_SCREEN_WIDTH/2-40, JX_SCREEN_HEIGHT-20-80, 80, 80) image:@"video_edit" action:@selector(editImageBtnAction:)];
  144. [_iv addSubview:editBtn];
  145. UIButton *confirmBtn = [self createButtonWithFrame:CGRectMake(JX_SCREEN_WIDTH-20-80, JX_SCREEN_HEIGHT-20-80, 80, 80) image:@"video_gou" action:@selector(confirmBtnAction:)];
  146. [_iv addSubview:confirmBtn];
  147. if (!self.isPhoto) {
  148. [self isVideoCustomView];
  149. }
  150. }
  151. - (void)initVideoCamera {
  152. if (self.isVideo) {
  153. _videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
  154. }
  155. _videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
  156. [_videoCamera addAudioInputsAndOutputs];
  157. _videoCamera.horizontallyMirrorFrontFacingCamera = YES; // 镜像
  158. // [_videoCamera rotateCamera];
  159. if (THE_DEVICE_HAVE_HEAD) {
  160. _cropFilter = [[GPUImageCropFilter alloc] initWithCropRegion:CGRectMake((1.0 - (480.0/640.0 - 0.13)) / 2, 0.0, 480.0/640.0 - 0.13,1.0)];
  161. }else {
  162. _cropFilter = [[GPUImageCropFilter alloc] initWithCropRegion:CGRectMake((1.0 - 480.0/640.0) / 2, 0.0, 480.0/640.0 ,1.0)];
  163. }
  164. [self setFilterGroup];
  165. [_videoCamera addTarget:_filterGroup];
  166. [_videoCamera startCameraCapture];
  167. [_filter addTarget:_cropFilter];
  168. //必须判定是否有闪光灯,否则如果没有闪光灯会崩溃
  169. if (_videoCamera.inputCamera.hasFlash) {
  170. [_videoCamera.inputCamera lockForConfiguration:nil];
  171. _videoCamera.inputCamera.flashMode = AVCaptureFlashModeAuto;
  172. [_videoCamera.inputCamera unlockForConfiguration];
  173. }
  174. }
  175. - (void)setFilterGroup {
  176. /// 滤镜分组
  177. _filterGroup = [[GPUImageFilterGroup alloc] init];
  178. // [self videoSetFilter];
  179. // 磨皮滤镜
  180. GPUImageBilateralFilter *bilateralFilter = [[GPUImageBilateralFilter alloc] init];
  181. [_filterGroup addFilter:bilateralFilter];
  182. _bilateralFilter = bilateralFilter;
  183. // 美白滤镜
  184. GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
  185. [_filterGroup addFilter:brightnessFilter];
  186. [_bilateralFilter setDistanceNormalizationFactor:MAXFLOAT];
  187. _brightnessFilter = brightnessFilter;
  188. // 设置滤镜组链
  189. [bilateralFilter addTarget:brightnessFilter];
  190. [_filterGroup setInitialFilters:@[bilateralFilter]];
  191. _filterGroup.terminalFilter = brightnessFilter;
  192. // 添加滤镜
  193. GPUImageFilter*filter = [[GPUImageFilter alloc] init];
  194. [_filterGroup addTarget:filter];
  195. _filter = filter;
  196. [_filterGroup addTarget:(GPUImageView *)self.view];
  197. }
  198. - (void)initPhotoCamera {
  199. if (!_stillCamera) {
  200. _stillCamera = [[GPUImageStillCamera alloc] init];
  201. _stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
  202. _stillCamera.horizontallyMirrorFrontFacingCamera = YES; // 镜像
  203. // [_stillCamera addTarget:_beautifyFilter];
  204. // GPUImageView *filterView = (GPUImageView *)self.view;
  205. // [_beautifyFilter addTarget:filterView];
  206. [_stillCamera startCameraCapture];
  207. }
  208. [self setFilterGroup];
  209. [_stillCamera addTarget:_filterGroup];
  210. [_stillCamera startCameraCapture];
  211. //必须判定是否有闪光灯,否则如果没有闪光灯会崩溃
  212. if (_stillCamera.inputCamera.hasFlash) {
  213. [_stillCamera.inputCamera lockForConfiguration:nil];
  214. _stillCamera.inputCamera.flashMode = AVCaptureFlashModeAuto;
  215. [_stillCamera.inputCamera unlockForConfiguration];
  216. }
  217. }
  218. #pragma mark - 单击拍照
  219. - (void)singlePress:(UITapGestureRecognizer *)tap {
  220. if (self.isVideo) {
  221. return;
  222. }
  223. self.isNotPhoto = NO;
  224. [self takePhoto];
  225. [self hideTime];
  226. }
  227. #pragma mark - 长按录像
  228. - (void)longPress:(UILongPressGestureRecognizer *)tap {
  229. if (self.isPhoto) {
  230. return;
  231. }
  232. if (tap.state == UIGestureRecognizerStateBegan) {
  233. self.isNotPhoto = YES;
  234. _isRecording = NO;
  235. [self takePhoto];
  236. [self showTime];
  237. }else if(tap.state == UIGestureRecognizerStateEnded) {
  238. self.isNotPhoto = YES;
  239. _isRecording = YES;
  240. [self takePhoto];
  241. }
  242. }
  243. #pragma mark - 拍照、录像事件处理
  244. - (void)takePhoto {
  245. if (self.isNotPhoto) {
  246. if (!_isRecording) {
  247. [self.scrollView setHidden:YES];
  248. [_photoCaptureButton setBackgroundImage:[UIImage imageNamed:_isPhoto ? @"stop" :@"stop_video"] forState:UIControlStateNormal];
  249. _isRecording = YES;
  250. [self startPhoto];
  251. _recordTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(recordTimerAction:) userInfo:nil repeats:YES];
  252. // [self noticnoticeLabelHiddeneLabelHidden:YES textType:1];
  253. }else {
  254. // [self.scrollView setHidden:NO];
  255. // if (_timerNum <= 0) {
  256. // return;
  257. // }
  258. [_photoCaptureButton setBackgroundImage:[UIImage imageNamed:_isPhoto ? @"start" : @"start_video"] forState:UIControlStateNormal];
  259. _isRecording = NO;
  260. [_recordTimer invalidate];
  261. _recordTimer = nil;
  262. [self endRecording];
  263. _timerNum = 0;
  264. _timeLabel.text = @"00:00";
  265. _playerView = [[UIView alloc] initWithFrame:self.view.bounds];
  266. [self.view addSubview:_playerView];
  267. _player= [JXVideoPlayer alloc];
  268. _player.type = JXVideoTypePreview;
  269. _player.isShowHide = YES; //播放中点击播放器便销毁播放器
  270. _player.didSendBtn = @selector(didSendBtn:);
  271. _player.didExitBtn = @selector(didExitBtn:);
  272. _player.isStartFullScreenPlay = YES; //全屏播放
  273. _player.isPreview = YES; // 这是预览
  274. _player.delegate = self;
  275. _player = [_player initWithParent:_playerView];
  276. _player.parent = _playerView;
  277. _player.videoFile = self.outputFileName;
  278. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  279. [_player switch];
  280. });
  281. // [self dismissViewControllerAnimated:YES completion:^{
  282. //
  283. // if ([self.cameraDelegate respondsToSelector:@selector(cameraVC:didFinishWithVideoPath:timeLen:)]) {
  284. // [self.cameraDelegate cameraVC:self didFinishWithVideoPath:self.outputFileName timeLen:self.timerNum];
  285. // }
  286. //
  287. // _timerNum = 0;
  288. // }];
  289. }
  290. }else{
  291. [_photoCaptureButton setEnabled:NO];
  292. // if (_beautyBtn.selected) {
  293. // [_stillCamera capturePhotoAsJPEGProcessedUpToFilter:_normalFilter withCompletionHandler:^(NSData *processedJPEG, NSError *error){
  294. //
  295. // [_photoCaptureButton setEnabled:YES];
  296. // UIImage *image = [UIImage imageWithData:processedJPEG];
  297. // CGFloat scale = JX_SCREEN_WIDTH / JX_SCREEN_HEIGHT;
  298. // CGFloat width = image.size.height * scale;
  299. // image = [self getImageByCuttingImage:image Rect:CGRectMake((image.size.width - width) / 2, 0, width, image.size.height)];
  300. // _iv.image = image;
  301. // _iv.hidden = NO;
  302. //
  303. // }];
  304. // }else {
  305. [_stillCamera capturePhotoAsJPEGProcessedUpToFilter:self.filter withCompletionHandler:^(NSData *processedJPEG, NSError *error){
  306. [_photoCaptureButton setEnabled:YES];
  307. UIImage *image = [UIImage imageWithData:processedJPEG];
  308. CGFloat scale = JX_SCREEN_WIDTH / JX_SCREEN_HEIGHT;
  309. CGFloat width = image.size.height * scale;
  310. image = [self getImageByCuttingImage:image Rect:CGRectMake((image.size.width - width) / 2, 0, width, image.size.height)];
  311. _iv.image = image;
  312. _iv.hidden = NO;
  313. }];
  314. // }
  315. }
  316. }
  317. // 随时切换模式
  318. - (void)switchSkinCare {
  319. self.scrollView.hidden = !self.scrollView.hidden;
  320. }
  321. #pragma mark Device Counts
  322. - (NSUInteger) cameraCount
  323. {
  324. return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
  325. }
  326. - (void)viewDidAppear:(BOOL)animated {
  327. [super viewDidAppear:animated];
  328. // 进入后隐藏状态栏
  329. [[UIApplication sharedApplication] setStatusBarHidden:YES];
  330. }
  331. - (void)viewWillDisappear:(BOOL)animated {
  332. [super viewWillDisappear:animated];
  333. // 离开时显示状态栏
  334. [[UIApplication sharedApplication] setStatusBarHidden:NO];
  335. }
  336. - (void)viewWillAppear:(BOOL)animated {
  337. [super viewWillAppear:animated];
  338. [[UIApplication sharedApplication] setStatusBarHidden:YES];
  339. [self hideTime];
  340. }
  341. - (void)hideTime {
  342. _noticeLabel.hidden = YES;
  343. _timeLabel.hidden = YES;
  344. _timeBGView.hidden = YES;
  345. }
  346. - (void)showTime {
  347. _noticeLabel.hidden = NO;
  348. _timeLabel.hidden = NO;
  349. _timeBGView.hidden = NO;
  350. }
  351. // 录制视频专有UI
  352. - (void) isVideoCustomView{
  353. _noticeLabel = [[UILabel alloc] initWithFrame:CGRectMake(45, 0, JX_SCREEN_WIDTH-45*2, 45)];
  354. _noticeLabel.center = self.view.center;
  355. _noticeLabel.textColor = [UIColor whiteColor];
  356. _noticeLabel.font = SYSFONT(15);
  357. _noticeLabel.numberOfLines = 2;
  358. _noticeLabel.backgroundColor = [UIColor clearColor];
  359. _noticeLabel.textAlignment = NSTextAlignmentCenter;
  360. [self.view addSubview:_noticeLabel];
  361. // [_noticeLabel release];
  362. // [self noticeLabelHidden:NO textType:1];
  363. //时间
  364. _timerNum = 0;
  365. _timeBGView = [[UIImageView alloc] initWithFrame:CGRectMake((JX_SCREEN_WIDTH-210)/2, THE_DEVICE_HAVE_HEAD ? JX_SCREEN_TOP/2+5 : JX_SCREEN_TOP/2-15, 210, 2)];
  366. // _timeBGView = [[UIImageView alloc] initWithFrame:CGRectMake((JX_SCREEN_WIDTH-210)/2, (JX_SCREEN_HEIGHT-JX_SCREEN_WIDTH)/2-35, 210, 2)];
  367. _timeBGView.image = [UIImage imageNamed:@"time_axis"];
  368. [self.view addSubview:_timeBGView];
  369. _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 55, 30)];
  370. _timeLabel.center = _timeBGView.center;
  371. _timeLabel.text = @"00:00";
  372. _timeLabel.textAlignment = NSTextAlignmentCenter;
  373. _timeLabel.textColor = [UIColor whiteColor];
  374. _timeLabel.shadowColor = [UIColor blackColor];
  375. _timeLabel.shadowOffset = CGSizeMake(1, 1);
  376. _timeLabel.backgroundColor = [UIColor clearColor];
  377. [self.view addSubview:_timeLabel];
  378. }
  379. // 设置提示label
  380. //-(void)noticeLabelHidden:(BOOL)hide textType:(int)type{
  381. // _noticeLabel.hidden = hide;
  382. // NSString * showStr = nil;
  383. // switch (type) {
  384. // case 1:
  385. // showStr = [NSString stringWithFormat:@"%@%d%@",Localized(@"recordVideoVC_Show1"),_maxTime,Localized(@"recordVideoVC_Show2")];
  386. // break;
  387. // case 2:
  388. // showStr = [NSString stringWithFormat:@"%@%ds",Localized(@"recordVideoViewController_LessThan"),_minTime];
  389. // break;
  390. // default:
  391. // break;
  392. // }
  393. // _noticeLabel.text = showStr;
  394. //}
  395. // 录制视频计时
  396. - (void)recordTimerAction:(NSTimer *)timer {
  397. _timerNum ++;
  398. NSInteger m = _timerNum/60;
  399. NSInteger n = _timerNum%60;
  400. NSString * labelTimeStr;
  401. labelTimeStr = [NSString stringWithFormat:@"%.2ld:%.2ld",m,n];
  402. _timeLabel.text = labelTimeStr;
  403. // if (_timerNum >= _maxTime) {
  404. // [_recordTimer invalidate];
  405. // _recordTimer = nil;
  406. // [self endRecording];
  407. // [self dismissViewControllerAnimated:YES completion:^{
  408. //
  409. // if ([self.cameraDelegate respondsToSelector:@selector(cameraVC:didFinishWithVideoPath:timeLen:)]) {
  410. // [self.cameraDelegate cameraVC:self didFinishWithVideoPath:self.outputFileName timeLen:self.timerNum];
  411. // }
  412. //
  413. // _timerNum = 0;
  414. // }];
  415. // }
  416. }
  417. // 设置录制视频filter
  418. - (void)videoSetFilter{
  419. // [_cropFilter addTarget:_beautifyFilter];
  420. [_filterGroup addTarget:_cropFilter];
  421. // [_filterGroup addTarget:_beautifyFilter];
  422. [_filterGroup setInitialFilters:[NSArray arrayWithObject:_cropFilter]];
  423. // [_filterGroup setTerminalFilter:_beautifyFilter];
  424. [_filterGroup forceProcessingAtSize:self.view.frame.size];
  425. [_filterGroup useNextFrameForImageCapture];
  426. [_videoCamera addTarget:_filterGroup];
  427. [_filterGroup addTarget:(GPUImageView *)self.view];
  428. }
  429. #pragma mark - 美颜 & 滤镜
  430. - (void) addPhotoStyle:(UIView *)parentView{
  431. _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, JX_SCREEN_WIDTH, 60)];
  432. _scrollView.backgroundColor = [UIColor clearColor];
  433. _scrollView.showsVerticalScrollIndicator = NO;
  434. _scrollView.showsHorizontalScrollIndicator = NO;
  435. [parentView addSubview:_scrollView];
  436. // NSArray *nameArray = @[Localized(@"JX_Standard"),Localized(@"JX_Pale"),Localized(@"JX_Dark"),Localized(@"JX_Morning"),Localized(@"JX_Dusk"),Localized(@"JX_Natural"),Localized(@"JX_Highlight")];
  437. //
  438. // _filterArray = @[
  439. // @{@"x":@1.1, @"y":@1.1},
  440. // @{@"x":@1.1, @"y":@0.5},
  441. // @{@"x":@0.9, @"y":@1.1},
  442. // @{@"x":@1.1, @"y":@1.3},
  443. // @{@"x":@1.1, @"y":@1.5},
  444. // @{@"x":@1.3, @"y":@1.1},
  445. // @{@"x":@1.5, @"y":@1.1},
  446. // ];
  447. //美颜
  448. GPUImageBeautifyFilter *BeautifyFilter = [[GPUImageBeautifyFilter alloc] init];
  449. //哈哈镜效果
  450. GPUImageStretchDistortionFilter *stretchDistortionFilter = [[GPUImageStretchDistortionFilter alloc] init];
  451. //黑白
  452. GPUImageGrayscaleFilter *GrayscaleFilter = [[GPUImageGrayscaleFilter alloc] init];
  453. //高斯模糊
  454. GPUImageGaussianBlurFilter *GaussianBlurFilter = [[GPUImageGaussianBlurFilter alloc] init];
  455. //边缘检测
  456. GPUImageXYDerivativeFilter *XYDerivativeFilter = [[GPUImageXYDerivativeFilter alloc] init];
  457. //怀旧
  458. GPUImageSepiaFilter *sepiaFilter = [[GPUImageSepiaFilter alloc] init];
  459. //反色
  460. GPUImageColorInvertFilter *invertFilter = [[GPUImageColorInvertFilter alloc] init];
  461. //饱和度
  462. GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init];
  463. // 亮度阈值
  464. GPUImageLuminanceThresholdFilter *LuminanceThresholdFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
  465. //去雾
  466. GPUImageHazeFilter *HazeFilter = [[GPUImageHazeFilter alloc] init];
  467. //初始化滤镜数组
  468. self.filterArray = @[BeautifyFilter,stretchDistortionFilter,GrayscaleFilter,GaussianBlurFilter,XYDerivativeFilter,sepiaFilter,invertFilter,saturationFilter,LuminanceThresholdFilter,HazeFilter];
  469. NSArray *nameArray = @[Localized(@"JX_CameraDefault"),Localized(@"JX_CameraSkinCare"),Localized(@"JX_CameraDistortingMirror"),Localized(@"JX_CameraBlackAndWhite"),Localized(@"JX_CameraGaussianBlur"),Localized(@"JX_CameraEdgeDetection"),Localized(@"JX_CameraNostalgia"),Localized(@"JX_CameraContrary"),Localized(@"JX_CameraSaturation"),Localized(@"JX_CameraThreshold"),Localized(@"JX_CameraFog")];
  470. UIImageView *lastImageView;
  471. for (NSInteger i = 0; i < nameArray.count; i ++) {
  472. // NSDictionary *dict = _filterArray[i];
  473. UIImage *inputImage = [UIImage imageNamed:@"zhang"];
  474. // GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
  475. // GPUImageHSBFilter *hsbFilter = [[GPUImageHSBFilter alloc] init];
  476. // [hsbFilter adjustBrightness:[dict[@"x"] floatValue]];
  477. // [hsbFilter adjustSaturation:[dict[@"y"] floatValue]];
  478. // [stillImageSource addTarget:hsbFilter];
  479. // [hsbFilter useNextFrameForImageCapture];
  480. // [stillImageSource processImage];
  481. // UIImage *image = [hsbFilter imageFromCurrentFramebuffer];
  482. if (i > 0) {
  483. [self.filterArray[i-1] useNextFrameForImageCapture];
  484. //获取数据源
  485. GPUImagePicture *stillImageSource=[[GPUImagePicture alloc]initWithImage:inputImage];
  486. [stillImageSource addTarget:self.filterArray[i-1]];
  487. //开始渲染
  488. [stillImageSource processImage];
  489. inputImage = [self.filterArray[i-1] imageFromCurrentFramebuffer];
  490. }
  491. UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetMaxX(lastImageView.frame) + 4, 0, 50, 60)];
  492. imageView.userInteractionEnabled = YES;
  493. imageView.tag = i;
  494. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectPhotoStyle:)];
  495. [imageView addGestureRecognizer:tap];
  496. imageView.image = inputImage;
  497. [_scrollView addSubview:imageView];
  498. lastImageView = imageView;
  499. if (i == 0) {
  500. imageView.layer.borderWidth = 2.0;
  501. imageView.layer.borderColor = [[UIColor yellowColor] CGColor];
  502. }
  503. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, imageView.frame.size.height - 15, imageView.frame.size.width, 15)];
  504. label.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
  505. label.text = nameArray[i];
  506. label.font = g_factory.font12;
  507. label.textAlignment = NSTextAlignmentCenter;
  508. label.textColor = [UIColor whiteColor];
  509. [imageView addSubview:label];
  510. [_photoStyleImages addObject:imageView];
  511. }
  512. _scrollView.contentSize = CGSizeMake(CGRectGetMaxX(lastImageView.frame) + 10, 0);
  513. }
  514. //- (void) setFilterStyle:(GPUImageOutput<GPUImageInput> *)filter{
  515. //
  516. // if ([filter isKindOfClass:[GPUImageSaturationFilter class]]) {
  517. // [(GPUImageSaturationFilter *)filter setSaturation:0.0];
  518. // }
  519. // if ([filter isKindOfClass:[GPUImageRGBFilter class]]) {
  520. // [(GPUImageRGBFilter *)filter setGreen:1.3];
  521. // }
  522. // if ([filter isKindOfClass:[GPUImageBrightnessFilter class]]) {
  523. // [(GPUImageBrightnessFilter *)filter setBrightness:.3];
  524. // }
  525. //}
  526. #pragma mark - 选择滤镜风格
  527. - (void) selectPhotoStyle:(UIGestureRecognizer *)tap{
  528. if (_isRecording) {
  529. [JXMyTools showTipView:Localized(@"JX_CannotSwitchDuringRecording")];
  530. return;
  531. }
  532. if (_beautyBtn.selected) {
  533. [JXMyTools showTipView:Localized(@"JX_PleaseOpenBeauty")];
  534. return;
  535. }
  536. UIView *view = tap.view;
  537. self.isCreateFilter = YES;
  538. if (view == _photoStyleImages[1]) {
  539. [self recoverFilterGroup];
  540. [_bilateralSld setValue:self.bilHis > 0 ? self.bilHis : 4.2];
  541. [_brightnessSld setValue:self.briHis> 0 ? self.briHis : 0.07];
  542. [_bilateralFilter setDistanceNormalizationFactor:[self getBilValue:self.bilHis > 0 ? self.bilHis : 4.2]];
  543. _brightnessFilter.brightness = self.briHis> 0 ? self.briHis : 0.07;
  544. return;
  545. }else {
  546. [_bilateralSld setValue:0];
  547. [_brightnessSld setValue:0];
  548. }
  549. for (UIImageView *imageView in _photoStyleImages) {
  550. if (view == imageView) {
  551. imageView.layer.borderWidth = 2.0;
  552. imageView.layer.borderColor = [[UIColor yellowColor] CGColor];
  553. }else {
  554. imageView.layer.borderWidth = 0.0;
  555. }
  556. }
  557. [self.videoCamera removeAllTargets];
  558. [_stillCamera removeAllTargets];
  559. if (view.tag > 1) {
  560. // 只处理正常和滤镜
  561. GPUImageFilter *filter = self.filterArray[view.tag-1];
  562. [filter addTarget:(GPUImageView *)self.view];
  563. if (self.isPhoto) {
  564. [_stillCamera addTarget:filter];
  565. }else {
  566. [self.videoCamera addTarget:filter];
  567. [filter addTarget:_cropFilter];
  568. }
  569. self.filter = filter;
  570. }else {
  571. if (self.isPhoto) {
  572. [self initPhotoCamera];
  573. }else {
  574. [self initVideoCamera];
  575. }
  576. }
  577. // [_beautifyFilter removeAllTargets];
  578. //
  579. // _beautifyFilter = [GPUImageBeautifyFilter alloc];
  580. //
  581. // _beautifyFilter.dict = _filterArray[view.tag];
  582. //
  583. // _beautifyFilter = [_beautifyFilter init];
  584. // if (self.isVideo) {
  585. // [self videoBeautyStyle];
  586. // }else if (self.isPhoto){
  587. // [self photoBeautyStyle];
  588. // }else {
  589. // [self videoBeautyStyle];
  590. //// [self photoBeautyStyle];
  591. // }
  592. // GPUImageOutput<GPUImageInput> *filter = _filterArray[view.tag];
  593. // [_stillCamera addTarget:filter];
  594. // GPUImageView *filterView = (GPUImageView *)self.view;
  595. // [filter addTarget:filterView];
  596. // self.filter = filter;
  597. }
  598. - (void)videoBeautyStyle {
  599. [_videoCamera removeAllTargets];
  600. [_cropFilter removeAllTargets];
  601. [_filterGroup removeAllTargets];
  602. [self videoSetFilter];
  603. }
  604. - (void)photoBeautyStyle {
  605. [_stillCamera removeAllTargets];
  606. [_stillCamera addTarget:_beautifyFilter];
  607. GPUImageView *filterView = (GPUImageView *)self.view;
  608. [_beautifyFilter addTarget:filterView];
  609. }
  610. // 截图
  611. - (UIImage *)getImageByCuttingImage:(UIImage *)image Rect:(CGRect)rect{
  612. //大图bigImage
  613. //定义myImageRect,截图的区域
  614. CGRect myImageRect = rect;
  615. UIImage* bigImage= image;
  616. CGImageRef imageRef = bigImage.CGImage;
  617. imageRef = CGImageCreateWithImageInRect(imageRef, myImageRect);
  618. CGSize size;
  619. size.width = rect.size.width;
  620. size.height = rect.size.height;
  621. UIGraphicsBeginImageContext(size);
  622. CGContextRef context = UIGraphicsGetCurrentContext();
  623. CGContextDrawImage(context, myImageRect, imageRef);
  624. UIImage* smallImage = [UIImage imageWithCGImage:imageRef];
  625. UIGraphicsEndImageContext();
  626. CFRelease(imageRef);
  627. return smallImage;
  628. }
  629. - (void)didSendBtn:(id)sender {
  630. [self dismissViewControllerAnimated:YES completion:^{
  631. if ([self.cameraDelegate respondsToSelector:@selector(cameraVC:didFinishWithVideoPath:timeLen:)]) {
  632. [self.cameraDelegate cameraVC:self didFinishWithVideoPath:self.outputFileName timeLen:self.timerNum];
  633. }
  634. _playerView = nil;
  635. _player = nil;
  636. }];
  637. }
  638. - (void)didExitBtn:(id)sender {
  639. _playerView = nil;
  640. _player = nil;
  641. [self hideTime];
  642. }
  643. // X
  644. - (void)cancelBtnAction:(UIButton *)btn {
  645. _isRecording = NO;
  646. [_recordTimer invalidate];
  647. _recordTimer = nil;
  648. [self dismissViewControllerAnimated:YES completion:^{
  649. [[GPUImageContext sharedImageProcessingContext].framebufferCache purgeAllUnassignedFramebuffers];
  650. }];
  651. }
  652. // 转换摄像头
  653. - (void)switchBtnAction:(UIButton *)btn {
  654. if (self.isVideo) {
  655. [_videoCamera rotateCamera];
  656. }else if (self.isPhoto) {
  657. [_stillCamera rotateCamera];
  658. }else {
  659. [_videoCamera rotateCamera];
  660. // [_stillCamera rotateCamera];
  661. }
  662. }
  663. // 闪光灯
  664. - (void)flashBtnAction:(UIButton *)btn {
  665. // if (self.isVideo) {
  666. // [_videoCamera.inputCamera lockForConfiguration:nil];
  667. // switch (_videoCamera.inputCamera.flashMode) {
  668. // case AVCaptureFlashModeAuto:
  669. // _videoCamera.inputCamera.flashMode = AVCaptureFlashModeOn;
  670. // [btn setImage:[UIImage imageNamed:@"flash_on"] forState:UIControlStateNormal];
  671. // break;
  672. // case AVCaptureFlashModeOn:
  673. // _videoCamera.inputCamera.flashMode = AVCaptureFlashModeOff;
  674. // [btn setImage:[UIImage imageNamed:@"flash_off"] forState:UIControlStateNormal];
  675. // break;
  676. // case AVCaptureFlashModeOff:
  677. // _videoCamera.inputCamera.flashMode = AVCaptureFlashModeAuto;
  678. // [btn setImage:[UIImage imageNamed:@"automatic"] forState:UIControlStateNormal];
  679. // break;
  680. //
  681. // default:
  682. // break;
  683. // }
  684. //
  685. // [_videoCamera.inputCamera unlockForConfiguration];
  686. // }else {
  687. [_stillCamera.inputCamera lockForConfiguration:nil];
  688. switch (_stillCamera.inputCamera.flashMode) {
  689. case AVCaptureFlashModeAuto:
  690. _stillCamera.inputCamera.flashMode = AVCaptureFlashModeOn;
  691. [btn setImage:[UIImage imageNamed:@"flash_on"] forState:UIControlStateNormal];
  692. break;
  693. case AVCaptureFlashModeOn:
  694. _stillCamera.inputCamera.flashMode = AVCaptureFlashModeOff;
  695. [btn setImage:[UIImage imageNamed:@"flash_off"] forState:UIControlStateNormal];
  696. break;
  697. case AVCaptureFlashModeOff:
  698. _stillCamera.inputCamera.flashMode = AVCaptureFlashModeAuto;
  699. [btn setImage:[UIImage imageNamed:@"automatic"] forState:UIControlStateNormal];
  700. break;
  701. default:
  702. break;
  703. }
  704. [_stillCamera.inputCamera unlockForConfiguration];
  705. // }
  706. }
  707. // 重新拍照
  708. - (void) cancelImageBtnAction:(UIButton *)btn {
  709. _iv.hidden = YES;
  710. _iv.image = nil;
  711. [[GPUImageContext sharedImageProcessingContext].framebufferCache purgeAllUnassignedFramebuffers];
  712. }
  713. // 编辑照片
  714. - (void) editImageBtnAction:(UIButton *)btn {
  715. KKImageEditorViewController *editor = [[KKImageEditorViewController alloc] initWithImage:_iv.image delegate:self];
  716. UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:editor];
  717. [self presentViewController:vc animated:YES completion:nil];
  718. }
  719. #pragma mark- 照片编辑后的回调
  720. - (void)imageDidFinishEdittingWithImage:(UIImage *)image asset:(PHAsset *)asset
  721. {
  722. _iv.image = image;
  723. }
  724. // 确定此照片
  725. - (void) confirmBtnAction:(UIButton *)btn {
  726. [self dismissViewControllerAnimated:YES completion:^{
  727. if ([self.cameraDelegate respondsToSelector:@selector(cameraVC:didFinishWithImage:)]) {
  728. [self.cameraDelegate cameraVC:self didFinishWithImage:_iv.image];
  729. }
  730. }];
  731. }
  732. #pragma mark - 美颜按鈕
  733. - (void) beautyBtnAction:(UIButton *)btn {
  734. if (!_baseView) {
  735. [self showBaseView];
  736. }
  737. [self setupBeautyView:YES];
  738. // if (_isRecording) {
  739. // [JXMyTools showTipView:Localized(@"JX_CannotSwitchDuringRecording")];
  740. // return;
  741. // }
  742. //
  743. // btn.selected = !btn.selected;
  744. //
  745. // if (btn.selected) {
  746. // [btn setImage:[UIImage imageNamed:@"camra_beauty_close"] forState:UIControlStateNormal];
  747. // if (self.isVideo) {
  748. // [self videoSkinCare];
  749. // }else if (self.isPhoto){
  750. // [self photoSkinCare];
  751. // } else {
  752. // [self videoSkinCare];
  753. //// [self photoSkinCare];
  754. // }
  755. //
  756. // }else {
  757. // [btn setImage:[UIImage imageNamed:@"camra_beauty"] forState:UIControlStateNormal];
  758. //
  759. // [_beautifyFilter removeAllTargets];
  760. // if (self.isVideo) {
  761. // [self videoCancelSkinCare];
  762. // }else if (self.isPhoto){
  763. // [self photoCancelSkinCare];
  764. // }else {
  765. // [self videoCancelSkinCare];
  766. //// [self photoCancelSkinCare];
  767. // }
  768. // }
  769. }
  770. // 开启美颜
  771. - (void)videoSkinCare {
  772. [_videoCamera removeAllTargets];
  773. [_beautifyFilter removeAllTargets];
  774. [_filterGroup removeAllTargets];
  775. [_cropFilter removeAllTargets];
  776. [_videoCamera addTarget:_cropFilter];
  777. [_cropFilter addTarget:(GPUImageView *)self.view];
  778. }
  779. - (void)photoSkinCare {
  780. [_stillCamera removeAllTargets];
  781. [_beautifyFilter removeAllTargets];
  782. // _normalFilter = [[GPUImageBrightnessFilter alloc] init];
  783. // [_stillCamera addTarget:_normalFilter];
  784. // [_normalFilter addTarget:(GPUImageView *)self.view];
  785. }
  786. //取消美颜
  787. - (void)videoCancelSkinCare {
  788. [_videoCamera removeAllTargets];
  789. [_cropFilter removeAllTargets];
  790. [_filterGroup removeAllTargets];
  791. [self videoSetFilter];
  792. }
  793. - (void)photoCancelSkinCare {
  794. [_stillCamera removeAllTargets];
  795. [_stillCamera addTarget:_beautifyFilter];
  796. GPUImageView *filterView = (GPUImageView *)self.view;
  797. [_beautifyFilter addTarget:filterView];
  798. }
  799. #pragma mark - 开始录制视频
  800. - (void)startPhoto {
  801. ///录制的视频会存储到该路径下 唯一
  802. NSString *pathToMovie = kCameraVideoPath;
  803. _outputFileName = pathToMovie;
  804. // [videoArray addObject:pathToMovie];
  805. NSLog(@"%@",pathToMovie);
  806. unlink([pathToMovie UTF8String]);
  807. NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
  808. // _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720, 720) fileType:AVFileTypeQuickTimeMovie outputSettings:nil];
  809. _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(((int)JX_SCREEN_WIDTH/16)*16, ((int)JX_SCREEN_HEIGHT/16)*16) fileType:AVFileTypeQuickTimeMovie outputSettings:nil];
  810. AudioChannelLayout channelLayout;
  811. memset(&channelLayout, 0, sizeof(AudioChannelLayout));
  812. channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
  813. NSDictionary *audioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
  814. [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,//制定编码算法
  815. [ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey,//声道
  816. [ NSNumber numberWithFloat: 16000.0 ], AVSampleRateKey,//采样率
  817. [ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
  818. [ NSNumber numberWithInt: 32000 ], AVEncoderBitRateKey,//编码率
  819. nil];
  820. [_movieWriter setHasAudioTrack:YES audioSettings:audioSettings];
  821. _movieWriter.hasAudioTrack = YES;
  822. _movieWriter.encodingLiveVideo = YES;
  823. _movieWriter.shouldPassthroughAudio = YES;
  824. // [_filterGroup addTarget:_movieWriter];
  825. [_videoCamera addAudioInputsAndOutputs];
  826. _videoCamera.audioEncodingTarget = _movieWriter;
  827. // if (_filterGroup.targets.count <= 0) {
  828. // [_cropFilter addTarget:_movieWriter];
  829. // }
  830. // else {
  831. // [_filterGroup addTarget:_movieWriter];
  832. // }
  833. [_cropFilter addTarget:_movieWriter];
  834. [_movieWriter startRecording];
  835. }
  836. ///完成录制
  837. - (void)endRecording {
  838. [_movieWriter finishRecording];
  839. [_cropFilter removeTarget:_movieWriter];
  840. [_beautifyFilter removeTarget:_movieWriter];
  841. [_filterGroup removeTarget:_movieWriter];
  842. _videoCamera.audioEncodingTarget = nil;
  843. // [self savePhotoCmare:videoArray.lastObject];
  844. }
  845. - (void)dealloc {
  846. NSLog(@"cameraVC dealloc");
  847. [_stillCamera stopCameraCapture];
  848. [_videoCamera stopCameraCapture];
  849. [_movieWriter encodingLiveVideo];
  850. [_movieWriter cancelRecording];
  851. [_beautifyFilter removeAllTargets];
  852. [_filterGroup removeAllTargets];
  853. [_cropFilter removeAllTargets];
  854. [_normalFilter removeAllTargets];
  855. [_player stop];
  856. [_recordTimer invalidate];
  857. _recordTimer = nil;
  858. _stillCamera = nil;
  859. _videoCamera = nil;
  860. _movieWriter = nil;
  861. _beautifyFilter = nil;
  862. _filterGroup = nil;
  863. _cropFilter = nil;
  864. _normalFilter = nil;
  865. _player = nil;
  866. }
  867. - (UIButton *)createButtonWithFrame:(CGRect)frame image:(NSString *)image action:(SEL)action {
  868. UIButton *button = [[UIButton alloc] initWithFrame:frame];
  869. button.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
  870. button.layer.masksToBounds = YES;
  871. button.layer.cornerRadius = button.frame.size.width/2;
  872. [button setImage:[UIImage scaleToSize:[UIImage imageNamed:image] size:CGSizeMake(32, 32)] forState:UIControlStateNormal];
  873. if (action == @selector(editImageBtnAction:)) { // 编辑图片有点大,要单独处理下
  874. [button setImage:[UIImage scaleToSize:[UIImage imageNamed:image] size:CGSizeMake(21, 21)] forState:UIControlStateNormal];
  875. }
  876. [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
  877. return button;
  878. }
  879. - (void)showBaseView {
  880. self.baseView = [[UIView alloc] initWithFrame:self.view.bounds];
  881. self.baseView.backgroundColor = [UIColor clearColor];
  882. self.baseView.hidden = YES;
  883. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideBaseView)];
  884. [self.baseView addGestureRecognizer:tap];
  885. [self.view addSubview:self.baseView];
  886. self.bigView = [[UIView alloc] initWithFrame:CGRectMake(0, JX_SCREEN_HEIGHT-100-JX_SCREEN_BOTTOM, JX_SCREEN_WIDTH, 100+JX_SCREEN_BOTTOM)];
  887. self.bigView.backgroundColor = HEXCOLOR(0x323232);
  888. [self.baseView addSubview:self.bigView];
  889. UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickBigView)];
  890. [self.bigView addGestureRecognizer:tap1];
  891. [self addPhotoStyle:self.bigView];
  892. [self initBottomView:self.bigView];
  893. UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_scrollView.frame)+20, JX_SCREEN_WIDTH, LINE_WH)];
  894. line.backgroundColor = THE_LINE_COLOR;
  895. [self.bigView addSubview:line];
  896. //滤镜
  897. self.filterBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_scrollView.frame)+20, JX_SCREEN_WIDTH/2, JX_SCREEN_BOTTOM)];
  898. [self.filterBtn setTitle:Localized(@"JX_CameraFilter") forState:UIControlStateNormal];
  899. [self.filterBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
  900. [self.filterBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
  901. [self.filterBtn.titleLabel setFont:SYSFONT(15)];
  902. [self.filterBtn addTarget:self action:@selector(didFilterBtn) forControlEvents:UIControlEventTouchUpInside];
  903. [self.bigView addSubview:self.filterBtn];
  904. UIView *lineF = [[UIView alloc] initWithFrame:CGRectMake(self.filterBtn.frame.size.width-LINE_WH, 12, LINE_WH, 49-12*2)];
  905. lineF.backgroundColor = THE_LINE_COLOR;
  906. [self.filterBtn addSubview:lineF];
  907. //美颜
  908. self.skinCareBtn = [[UIButton alloc] initWithFrame:CGRectMake(JX_SCREEN_WIDTH/2, self.filterBtn.frame.origin.y, JX_SCREEN_WIDTH/2, self.filterBtn.frame.size.height)];
  909. [self.skinCareBtn setTitle:Localized(@"JX_CameraSkinCare") forState:UIControlStateNormal];
  910. [self.skinCareBtn.titleLabel setFont:SYSFONT(15)];
  911. [self.skinCareBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
  912. [self.skinCareBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
  913. [self.skinCareBtn addTarget:self action:@selector(didBeautyBtn) forControlEvents:UIControlEventTouchUpInside];
  914. [self.bigView addSubview:self.skinCareBtn];
  915. }
  916. - (void)setupBeautyView:(BOOL)isFilter {
  917. self.baseView.hidden = NO;
  918. _scrollView.hidden = !isFilter;
  919. _bottomControlView.hidden = isFilter;
  920. [self.filterBtn setSelected:isFilter];
  921. [self.skinCareBtn setSelected:!isFilter];
  922. }
  923. - (void)initBottomView:(UIView *)parentView
  924. {
  925. _bottomControlView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, JX_SCREEN_WIDTH, 60)];
  926. [parentView addSubview:_bottomControlView];
  927. //磨皮
  928. UILabel *bilateralL = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 40, 25)];
  929. bilateralL.text = Localized(@"JX_CameraExfoliating");
  930. bilateralL.font = [UIFont systemFontOfSize:14];
  931. bilateralL.textColor = [UIColor whiteColor];
  932. [_bottomControlView addSubview:bilateralL];
  933. UISlider *bilateralSld = [[UISlider alloc] initWithFrame:CGRectMake(50, 0, JX_SCREEN_WIDTH-100, 30)
  934. ];
  935. bilateralSld.maximumValue = 6;
  936. [bilateralSld addTarget:self action:@selector(bilateralFilter:) forControlEvents:UIControlEventValueChanged];
  937. [_bottomControlView addSubview:bilateralSld];
  938. _bilateralSld = bilateralSld;
  939. //美白
  940. UILabel *brightnessL = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 40, 25)];
  941. brightnessL.text = Localized(@"JX_CameraWhitening");
  942. brightnessL.font = [UIFont systemFontOfSize:14];
  943. brightnessL.textColor = [UIColor whiteColor];
  944. [_bottomControlView addSubview:brightnessL];
  945. UISlider *brightnessSld = [[UISlider alloc] initWithFrame:CGRectMake(50, 40, JX_SCREEN_WIDTH-100, 30)
  946. ];
  947. brightnessSld.minimumValue = 0;
  948. brightnessSld.maximumValue = 0.1;
  949. [brightnessSld addTarget:self action:@selector(brightnessFilter:) forControlEvents:UIControlEventValueChanged];
  950. [_bottomControlView addSubview:brightnessSld];
  951. _brightnessSld = brightnessSld;
  952. }
  953. //点击滤镜
  954. - (void)didFilterBtn {
  955. [self setupBeautyView:YES];
  956. }
  957. //点击美颜
  958. - (void)didBeautyBtn {
  959. [self setupBeautyView:NO];
  960. }
  961. #pragma mark - 调整磨皮
  962. - (void)bilateralFilter:(UISlider *)slider {
  963. [self recoverFilterGroup];
  964. //值越小,磨皮效果越好
  965. [_bilateralFilter setDistanceNormalizationFactor:[self getBilValue:slider.value]];
  966. self.bilHis = slider.value;
  967. NSLog(@"------调整磨皮 = %f - %f - %f",[self getBilValue:slider.value],(ldexp(slider.value, 10)),slider.value);
  968. }
  969. #pragma mark - 调整亮度
  970. - (void)brightnessFilter:(UISlider *)slider {
  971. [self recoverFilterGroup];
  972. _brightnessFilter.brightness = slider.value;
  973. self.briHis = slider.value;
  974. NSLog(@"------调整亮度 = %f",slider.value);
  975. }
  976. // 恢复调整状态下的磨皮和亮度
  977. - (void)recoverFilterGroup {
  978. if (self.isCreateFilter) {
  979. if (self.isPhoto) {
  980. [_stillCamera removeAllTargets];
  981. [self setFilterGroup];
  982. [_stillCamera addTarget:_filterGroup];
  983. [_stillCamera startCameraCapture];
  984. }else {
  985. [_videoCamera removeAllTargets];
  986. [self setFilterGroup];
  987. [_videoCamera addTarget:_filterGroup];
  988. [_videoCamera startCameraCapture];
  989. }
  990. self.isCreateFilter = NO;
  991. UIView *view = _photoStyleImages[1];
  992. for (UIImageView *imageView in _photoStyleImages) {
  993. if (view == imageView) {
  994. imageView.layer.borderWidth = 2.0;
  995. imageView.layer.borderColor = [[UIColor yellowColor] CGColor];
  996. }else {
  997. imageView.layer.borderWidth = 0.0;
  998. }
  999. }
  1000. }
  1001. }
  1002. - (CGFloat)getBilValue:(CGFloat)value {
  1003. CGFloat maxValue = 10;
  1004. CGFloat va = maxValue - value;
  1005. va = 60000 / (ldexp(value, 10));
  1006. return va;
  1007. }
  1008. - (void)hideBaseView {
  1009. self.baseView.hidden = YES;
  1010. }
  1011. - (void)clickBigView {}
  1012. @end