GPUImage图像处理源码精讲(二) -- 渲染效果

渲染效果

这篇是GPUImage图像处理代码最后一篇,下面希望小编分析IOS哪些框架,大家可以在评论区进行留言,小编会第一时间展开源码分析阅读。

前一篇,了解了关于UIImage转换成为GPUImage的大致过程,虽然代码很长,但是,我们领略了基本思想。今天我们来关注一个这个GPUImage核心渲染是如何操作的,这里面应用了一些图像,像素点等知识,需要的小伙伴可以自行了解。我们主要看设计思路。

渲染代码

代码取自第一篇中的示例代码。我们进入一个Filter来看一下具体操作,就从褐色过滤器来关注。

 GPUImageSepiaFilter *stillImageFilter = [[GPUImageSepiaFilter alloc] init];
 
    GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    brightnessFilter.brightness = 0.9;
    
    GPUImageExposureFilter *exposureFilter = [[GPUImageExposureFilter alloc] init];
    exposureFilter.exposure = 4.0;

GPUImageSepiaFilter

已进入就发现,这个类是通过GPUImageColorMatrixFilter来实现的,查看GPUImageColorMatrixFilter。

#import "GPUImageColorMatrixFilter.h"

/// Simple sepia tone filter
@interface GPUImageSepiaFilter : GPUImageColorMatrixFilter

@end
#import "GPUImageFilter.h"

/** Transforms the colors of an image by applying a matrix to them
 */
@interface GPUImageColorMatrixFilter : GPUImageFilter
{
    GLint colorMatrixUniform;
    GLint intensityUniform;
}

/** A 4x4 matrix used to transform each color in an image
 */
@property(readwrite, nonatomic) GPUMatrix4x4 colorMatrix;

/** The degree to which the new transformed color replaces the original color for each pixel
 */
@property(readwrite, nonatomic) CGFloat intensity;

@end

通过GPUImageColorMatrixFilter定义了两个成员属性:

  1. 颜色矩阵(colorMatrixUniform);
  2. 强度均匀(intensityUniform);
@property(readwrite, nonatomic) GPUMatrix4x4 colorMatrix;

A 4x4 matrix used to transform each color in an image
4x4矩阵,用于转换图像中的每种颜色

@property(readwrite, nonatomic) CGFloat intensity;

The degree to which the new transformed color replaces the original color for each pixel
新的变换颜色替换每个像素的原始颜色的程度

在这里,我们看到GPUImage在处理颜色问题上,使用了44的颜色矩阵,来显示不同颜色。也就是一个图片是由这个44颜色矩阵决定的。

GPUImageSepiaFilter初始化

我们看到只调用alloc init就可以使用,是因为init方法中就对颜色矩阵进行了处理。

- (id)init;
{
    if (!(self = [super init]))
    {
		return nil;
    }
    
    self.intensity = 1.0;
    
    self.colorMatrix = (GPUMatrix4x4){
        {0.3588, 0.7044, 0.1368, 0.0},
        {0.2990, 0.5870, 0.1140, 0.0},
        {0.2392, 0.4696, 0.0912 ,0.0},
        {0,0,0,1.0},
    };

    return self;
}
  1. 颜色强度:默认为1,这样是颜色均衡的;
  2. 颜色矩阵;
self.colorMatrix = (GPUMatrix4x4){
        {0.3588, 0.7044, 0.1368, 0.0},
        {0.2990, 0.5870, 0.1140, 0.0},
        {0.2392, 0.4696, 0.0912 ,0.0},
        {0,0,0,1.0},
    };

为此,我们也可以在外面修改这个强度。强度越大,颜色越深,相反,颜色越浅。

stillImageFilter.intensity = 3.0;

类比推理,GPUImage带颜色滤镜都是通过修改颜色矩阵和强度来改变颜色不同颜色矩阵的,这样,我们就可以自定义颜色滤镜了。

自定义过滤效果

  1. 继承GPUImageColorMatrixFilter;
  2. 初始化中,设置强度为1;
self.intensity = 1.0;

3.初始化中,设置颜色矩阵;

self.colorMatrix = (GPUMatrix4x4){
        {0.3588, 0.7144, 0.1368, 0.0},
        {0.2990, 0.5870, 0.1540, 0.0},
        {0.2692, 0.7696, 0.0912 ,0.0},
        {0,0,0,1.0},
    };

注意: IOS开发中的颜色设置都是在0.0~1.0之间的。表示的是颜色的强度和百分比,在设置RGBA时候,我们传入的参数都是在0.0~1.0之间的。因此,注意这里面的颜色矩阵传入的数字是0.0~1.0之间的数值。

GPUImageBrightnessFilter 和 GPUImageExposureFilter

我们既然知道了颜色过滤器可以继承,如果不带颜色效果,我们该怎么做呢。带这个问题,我们继续看GPUImage是如何操作的。

#import "GPUImageFilter.h"
@interface GPUImageBrightnessFilter : GPUImageFilter
{
    GLint brightnessUniform;
}

// Brightness ranges from -1.0 to 1.0, with 0.0 as the normal level
@property(readwrite, nonatomic) CGFloat brightness; 

@end
#import "GPUImageFilter.h"

/**
 * 设置曝光效果
 */
@interface GPUImageExposureFilter : GPUImageFilter
{
    GLint exposureUniform;
}

// Exposure ranges from -10.0 to 10.0, with 0.0 as the normal level
@property(readwrite, nonatomic) CGFloat exposure; 

@end

这两个类都继承了GPUImageFilter,因此,我们类比推理。不带颜色的类是继承自GPUImageFilter,并且每个不同的过滤器设置了不同的强度和范围。
我们在外部调用,就可以直接改变光亮和曝光强度。但仅仅这些是不够的,你还需要复制一段C语言解析颜色的方法。

#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageExposureFragmentShaderString = SHADER_STRING
(
 varying highp vec2 textureCoordinate;
 
 uniform sampler2D inputImageTexture;
 uniform highp float exposure;
 
 void main()
 {
     highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     
     gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);
 }
);
#else
NSString *const kGPUImageExposureFragmentShaderString = SHADER_STRING
(
 varying vec2 textureCoordinate;
 
 uniform sampler2D inputImageTexture;
 uniform float exposure;
 
 void main()
 {
     vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     
     gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);
 }
);
#endif

这样就可以自定义非颜色的过滤器了。

开始渲染

[stillImageSource addTarget:stillImageFilter];
[stillImageSource processImage];
UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentFramebuffer];
  1. 将滤镜添加到图片上;
  2. 手动捕捉滤镜;
  3. 开始渲染图片;
  4. 从缓存中获得图片;

总结

这就是GPUImage对图片进行渲染的操作,对影片,视频,动态图片渲染也是同样的操作,当需要时候,我们可以自定义操作。关于GPUImage图像源码分析到此就告于段落了。

中文源码下载

中文源码下载:GitHub.

你可能感兴趣的:(源码分析)