- (void)reloadFilter{ /* 移除所有的下一级滤镜对象 */ [self.filter removeAllTargets]; [self.blendFilter removeAllTargets]; [self.uiElementInput removeAllTargets]; [self.videoCamera removeAllTargets]; [self.output removeAllTargets]; [self.cropfilter removeAllTargets]; if (self.beautyFace) { self.output = [[LFGPUImageEmptyFilter alloc] init]; self.filter = [[LFGPUImageBeautyFilter alloc] init]; self.beautyFilter = (LFGPUImageBeautyFilter*)self.filter; } else { self.output = [[LFGPUImageEmptyFilter alloc] init]; self.filter = [[LFGPUImageEmptyFilter alloc] init]; self.beautyFilter = nil; } ///< 调节镜像 [self reloadMirror]; ///< 480*640 比例为4:3 强制转换为16:9 if([self.configuration.avSessionPreset isEqualToString:AVCaptureSessionPreset640x480]){ /* 图片宽 = 像素宽 / 分辨率宽 图片高 = 像素高 / 分辨率高 CropRegion: 在图片内裁剪,宽高按比例默认0.0~1.0,0.0-0.0位于图片左上角 假设一张图片size=100x100, 如果横屏裁切后展示的区域是CGRectMake(0, 12.5, 100, 75) 如果竖屏裁切后的展示区域是CGRectMake(12.5, 0, 75, 100) */ CGRect cropRect = self.configuration.landscape ? CGRectMake(0, 0.125, 1, 0.75) : CGRectMake(0.125, 0, 0.75, 1); self.cropfilter = [[GPUImageCropFilter alloc] initWithCropRegion:cropRect]; [self.videoCamera addTarget:self.cropfilter]; [self.cropfilter addTarget:self.filter]; }else{ /* 将滤镜添加到摄像头 */ [self.videoCamera addTarget:self.filter]; } /* 每个处理环节都是从上一个获取图像数据,进行处理后传递给下一个,下游的处理对象被称之为上一步的tatget 使用 addTarget: 为处理链路添加每个环节的对象 */ //< 添加水印 if(self.warterMarkView){ /* 要理解它的实现原理,需要搞懂GPUImageUIElement和GPUImageAlphaBlendFilter。 GPUImageUIElement的作用是把一个视图的layer通过CALayer的renderInContext:方法把layer转化为image, 然后作为OpenGL的纹理传给GPUImageAlphaBlendFilter。 而GPUImageAlphaBlendFilter则是一个两输入的blend filter, 第一个输入是摄像头数据, 第二个输入是刚刚提到的GPUImageUIElement的数据, GPUImageAlphaBlendFilter将这两个输入做alpha blend,可以简单的理解为将第二个输入叠加到第一个的上面, */ /* 双重滤镜叠加效果(并联) fileter滤镜->blendFilter滤镜->gpuImageView展示 uiElementInput->blendFilter滤镜->gpuImageView展示 uiElementInput: 只有初始化的水印图片,注释 [self.filter addTarget:self.blendFilter] , 屏幕上只有水印录像没有实时影像 filter: 实时影像 */ [self.filter addTarget:self.blendFilter]; [self.uiElementInput addTarget:self.blendFilter]; [self.blendFilter addTarget:self.gpuImageView]; if(self.saveLocalVideo) [self.blendFilter addTarget:self.movieWriter]; [self.filter addTarget:self.output]; [self.uiElementInput update]; // }else{ [self.filter addTarget:self.output]; [self.output addTarget:self.gpuImageView]; if(self.saveLocalVideo) [self.output addTarget:self.movieWriter]; } // 设置渲染的区域 [self.filter forceProcessingAtSize:self.configuration.videoSize]; [self.output forceProcessingAtSize:self.configuration.videoSize]; [self.blendFilter forceProcessingAtSize:self.configuration.videoSize]; [self.uiElementInput forceProcessingAtSize:self.configuration.videoSize]; /* 为什么要使用output? 在水印判断代码中最后都添加了output的这个target? 首先filter分为美颜与普通,filter本身并不携带水印, 其次output也可以省去,那么就需要if和else都调用 setFrameProcessingCompletionBlock output充当一个汇总,并且初始化的时候是 LFGPUImageEmptyFilter ,并不做二次滤镜效果 */ //< 输出数据 __weak typeof(self) _self = self; [self.output setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) { [_self processVideo:output]; }]; }