GPUImage--美颜滤镜GPUImageBeautifyFilter

来源:互联网 发布:西游记 女儿情 知乎 编辑:程序博客网 时间:2024/05/02 05:01

关于GPUimage的介绍请看这里GPUImage:滤镜、美颜、视频流处理

美颜只是不同滤镜组合起来的效果,实际上美颜也是一种滤镜,它的需求较多,于是自称一派。


GPUImageBeautifyFilter

/*GPUImageBeautifyFilter是基于GPUImage的实时美颜滤镜中的美颜滤镜,包括GPUImageBilateralFilter、GPUImageCannyEdgeDetectionFilter、GPUImageCombinationFilter、GPUImageHSBFilter。*/

在GPUImageBeautifyFilter.h中有:分别创建对应上面的对象

#import "GPUImage.h"@class GPUImageCombinationFilter;@interface GPUImageBeautifyFilter : GPUImageFilterGroup {    GPUImageBilateralFilter *bilateralFilter;    GPUImageCannyEdgeDetectionFilter *cannyEdgeFilter;    GPUImageCombinationFilter *combinationFilter;    GPUImageHSBFilter *hsbFilter;}@end

绘制流程分为:

  1. 准备纹理
  2. 绘制纹理
  3. 显示处理后的纹理

一、 准备纹理:这里用到的类
[GPUImageVideoCamera] -
[GPUImageBeautifyFilter] -
[GPUImageBilateralFliter] -
[GPUImageCombinationFilter] -
[GPUImageCannyEdgeDetectionFilter] -

准备 过程:

第一个纹理
1、GPUImageVideoCamera捕获摄像头图像
调用newFrameReadyAtTime: atIndex:通知GPUImageBeautifyFilter;
2、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:
通知GPUImageBilateralFliter输入纹理已经准备好;
第二个纹理:
3、GPUImageBilateralFliter 绘制图像后,
informTargetsAboutNewFrameAtTime(),
调用setInputFramebufferForTarget: atIndex:
把绘制的图像设置为GPUImageCombinationFilter输入纹理,
并通知GPUImageCombinationFilter纹理已经绘制完毕;
4、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:
通知 GPUImageCannyEdgeDetectionFilter输入纹理已经准备好;
第三个纹理:
5、同3,GPUImageCannyEdgeDetectionFilter 绘制图像后,
把图像设置为GPUImageCombinationFilter输入纹理;
6、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:
通知 GPUImageCombinationFilter输入纹理已经准备好;

原文:http://blog.sina.com.cn/s/blog_61bc01360102wpl2.html

二、绘制纹理:

7、判断纹理数量
GPUImageCombinationFilter判断是否有三个纹理,三个纹理都已经准备好后
调用GPUImageThreeInputFilter的绘制函数renderToTextureWithVertices: textureCoordinates:,
图像绘制完后,把图像设置为GPUImageHSBFilter的输入纹理,
通知GPUImageHSBFilter纹理已经绘制完毕;
8、绘制纹理
GPUImageHSBFilter调用renderToTextureWithVertices:
textureCoordinates:绘制图像,
完成后把图像设置为GPUImageView的输入纹理,并通知GPUImageView输入纹理已经绘制完毕;

显示纹理

9、GPUImageView把输入纹理绘制到自己的帧缓存,然后通过
[self.context presentRenderbuffer:GL_RENDERBUFFER];显示到UIView上。

GPUImageBeautifyFilter.m文件是这样的

////  GPUImageBeautifyFilter.m//  BeautifyFaceDemo////  Created by guikz on 16/4/28.//  Copyright © 2016年 guikz. All rights reserved.//#import "GPUImageBeautifyFilter.h"// Internal CombinationFilter(It should not be used outside)@interface GPUImageCombinationFilter : GPUImageThreeInputFilter{    GLint smoothDegreeUniform;}@property (nonatomic, assign) CGFloat intensity;@endNSString *const kGPUImageBeautifyFragmentShaderString = SHADER_STRING( varying highp vec2 textureCoordinate; varying highp vec2 textureCoordinate2; varying highp vec2 textureCoordinate3; uniform sampler2D inputImageTexture; uniform sampler2D inputImageTexture2; uniform sampler2D inputImageTexture3; uniform mediump float smoothDegree; void main() {     highp vec4 bilateral = texture2D(inputImageTexture, textureCoordinate);     highp vec4 canny = texture2D(inputImageTexture2, textureCoordinate2);     highp vec4 origin = texture2D(inputImageTexture3,textureCoordinate3);     highp vec4 smooth;     lowp float r = origin.r;     lowp float g = origin.g;     lowp float b = origin.b;     if (canny.r < 0.2 && r > 0.3725 && g > 0.1568 && b > 0.0784 && r > b && (max(max(r, g), b) - min(min(r, g), b)) > 0.0588 && abs(r-g) > 0.0588) {         smooth = (1.0 - smoothDegree) * (origin - bilateral) + bilateral;     }     else {         smooth = origin;     }     smooth.r = log(1.0 + 0.2 * smooth.r)/log(1.2);     smooth.g = log(1.0 + 0.2 * smooth.g)/log(1.2);     smooth.b = log(1.0 + 0.2 * smooth.b)/log(1.2);     gl_FragColor = smooth; } );@implementation GPUImageCombinationFilter- (id)init {    if (self = [super initWithFragmentShaderFromString:kGPUImageBeautifyFragmentShaderString]) {        smoothDegreeUniform = [filterProgram uniformIndex:@"smoothDegree"];    }    self.intensity = 0.5;    return self;}- (void)setIntensity:(CGFloat)intensity {    _intensity = intensity;    [self setFloat:intensity forUniform:smoothDegreeUniform program:filterProgram];}@end@implementation GPUImageBeautifyFilter- (id)init;{    if (!(self = [super init]))    {        return nil;    }    // First pass: face smoothing filter    bilateralFilter = [[GPUImageBilateralFilter alloc] init];    bilateralFilter.distanceNormalizationFactor = 4.0;    [self addFilter:bilateralFilter];    // Second pass: edge detection    cannyEdgeFilter = [[GPUImageCannyEdgeDetectionFilter alloc] init];    [self addFilter:cannyEdgeFilter];    // Third pass: combination bilateral, edge detection and origin    combinationFilter = [[GPUImageCombinationFilter alloc] init];    [self addFilter:combinationFilter];    // Adjust HSB    hsbFilter = [[GPUImageHSBFilter alloc] init];    [hsbFilter adjustBrightness:1.1];    [hsbFilter adjustSaturation:1.1];    [bilateralFilter addTarget:combinationFilter];    [cannyEdgeFilter addTarget:combinationFilter];    [combinationFilter addTarget:hsbFilter];    self.initialFilters = [NSArray arrayWithObjects:bilateralFilter,cannyEdgeFilter,combinationFilter,nil];    self.terminalFilter = hsbFilter;    return self;}#pragma mark 绘制第一个纹理- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;{    for (GPUImageOutput<GPUImageInput> *currentFilter in self.initialFilters)    {        if (currentFilter != self.inputFilterToIgnoreForUpdates)        {            if (currentFilter == combinationFilter) {                textureIndex = 2;            }            [currentFilter newFrameReadyAtTime:frameTime atIndex:textureIndex];        }    }}- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;{    for (GPUImageOutput<GPUImageInput> *currentFilter in self.initialFilters)    {        if (currentFilter == combinationFilter) {            textureIndex = 2;        }        [currentFilter setInputFramebuffer:newInputFramebuffer atIndex:textureIndex];    }}@end
2 0
原创粉丝点击