- (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];
}];
}