GPUImage源码解读(二十二)

GPUImage源码+demo 本资源包含开源库GPUImage源码和使用demo,经本人测试,库完美可用,能够实现静态图片和视频的滤镜处理。很方便,还可以自定义。 立即下载

GPUImageFourInputFilter 可以接收四个帧缓存对象的输入。它的作用可以将四个帧缓存对象的输入合并成一个帧缓存对象的输出。它继承自GPUImageThreeInputFilter,与GPUImageTwoInputFilter、GPUImageThreeInputFilter类似,主要增加了第四个帧缓存对象处理的相关操作。 philm gpuimage 版本没有这个类

GPUImageFourInputFilter github地址 下面也会有全部代码

  • 实例变量。主要增加了与第四个帧缓存对象相关的实例变量。
#import "GPUImageThreeInputFilter.h"

extern NSString *const kGPUImageFourInputTextureVertexShaderString;

@interface GPUImageFourInputFilter : GPUImageThreeInputFilter
{
    GPUImageFramebuffer *fourthInputFramebuffer;

    GLint filterFourthTextureCoordinateAttribute;
    GLint filterInputTextureUniform4;
    GPUImageRotationMode inputRotation4;
    GLuint filterSourceTexture4;
    CMTime fourthFrameTime;

    BOOL hasSetThirdTexture, hasReceivedFourthFrame, fourthFrameWasVideo;
    BOOL fourthFrameCheckDisabled;
}

- (void)disableFourthFrameCheck;

@end
  • 方法列表。 GPUImageFourInputFilter与GPUImageTwoInputFilter、GPUImageThreeInputFilter相比,它们的一些关键方法的逻辑都比较类似。
NSString *const kGPUImageFourInputTextureVertexShaderString = SHADER_STRING
(
 attribute vec4 position;
 attribute vec4 inputTextureCoordinate;
 attribute vec4 inputTextureCoordinate2;
 attribute vec4 inputTextureCoordinate3;
 attribute vec4 inputTextureCoordinate4;

 varying vec2 textureCoordinate;
 varying vec2 textureCoordinate2;
 varying vec2 textureCoordinate3;
 varying vec2 textureCoordinate4;

 void main()
 {
     gl_Position = position;
     textureCoordinate = inputTextureCoordinate.xy;
     textureCoordinate2 = inputTextureCoordinate2.xy;
     textureCoordinate3 = inputTextureCoordinate3.xy;
     textureCoordinate4 = inputTextureCoordinate4.xy;
 }
);

@implementation GPUImageFourInputFilter

- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;
{
    if (!(self = [self initWithVertexShaderFromString:kGPUImageFourInputTextureVertexShaderString fragmentShaderFromString:fragmentShaderString]))
    {
        return nil;
    }

    return self;
}

- (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString;
{
    if (!(self = [super initWithVertexShaderFromString:vertexShaderString fragmentShaderFromString:fragmentShaderString]))
    {
        return nil;
    }

    inputRotation4 = kGPUImageNoRotation;

    hasSetThirdTexture = NO;

    hasReceivedFourthFrame = NO;
    fourthFrameWasVideo = NO;
    fourthFrameCheckDisabled = NO;

    fourthFrameTime = kCMTimeInvalid;

    runSynchronouslyOnVideoProcessingQueue(^{
        [GPUImageContext useImageProcessingContext];
        filterFourthTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate4"];

        filterInputTextureUniform4 = [filterProgram uniformIndex:@"inputImageTexture4"]; // This does assume a name of "inputImageTexture3" for the third input texture in the fragment shader
        glEnableVertexAttribArray(filterFourthTextureCoordinateAttribute);
    });

    return self;
}

- (void)initializeAttributes;
{
    [super initializeAttributes];
    [filterProgram addAttribute:@"inputTextureCoordinate4"];
}
// 增加方法
- (void)disableFourthFrameCheck;
{
    fourthFrameCheckDisabled = YES;
}
// 重写方法
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
{
    if (self.preventRendering)
    {
        [firstInputFramebuffer unlock];
        [secondInputFramebuffer unlock];
        [thirdInputFramebuffer unlock];
        [fourthInputFramebuffer unlock];
        return;
    }

    [GPUImageContext setActiveShaderProgram:filterProgram];
    outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO];
    [outputFramebuffer activateFramebuffer];
    if (usingNextFrameForImageCapture)
    {
        [outputFramebuffer lock];
    }

    [self setUniformsForProgramAtIndex:0];

    glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);
    glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, [firstInputFramebuffer texture]);
    glUniform1i(filterInputTextureUniform, 2);

     // 激活纹理对象
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, [secondInputFramebuffer texture]);
    glUniform1i(filterInputTextureUniform2, 3);

    glActiveTexture(GL_TEXTURE4);
    glBindTexture(GL_TEXTURE_2D, [thirdInputFramebuffer texture]);
    glUniform1i(filterInputTextureUniform3, 4);

    glActiveTexture(GL_TEXTURE5);
    glBindTexture(GL_TEXTURE_2D, [fourthInputFramebuffer texture]);
    glUniform1i(filterInputTextureUniform4, 5);

    glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
    glVertexAttribPointer(filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates);
    glVertexAttribPointer(filterSecondTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [[self class] textureCoordinatesForRotation:inputRotation2]);
    glVertexAttribPointer(filterThirdTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [[self class] textureCoordinatesForRotation:inputRotation3]);
    glVertexAttribPointer(filterFourthTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [[self class] textureCoordinatesForRotation:inputRotation4]);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    [firstInputFramebuffer unlock];
    [secondInputFramebuffer unlock];
    [thirdInputFramebuffer unlock];
    [fourthInputFramebuffer unlock];
    if (usingNextFrameForImageCapture)
    {
        dispatch_semaphore_signal(imageCaptureSemaphore);
    }
}

- (NSInteger)nextAvailableTextureIndex;
{
    if (hasSetThirdTexture)
    {
        return 3;
    }
    else if (hasSetSecondTexture)
    {
        return 2;
    }
    else if (hasSetFirstTexture)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;
{
    if (textureIndex == 0)
    {
        firstInputFramebuffer = newInputFramebuffer;
        hasSetFirstTexture = YES;
        [firstInputFramebuffer lock];
    }
    else if (textureIndex == 1)
    {
        secondInputFramebuffer = newInputFramebuffer;
        hasSetSecondTexture = YES;
        [secondInputFramebuffer lock];
    }
    else if (textureIndex == 2)
    {
        thirdInputFramebuffer = newInputFramebuffer;
        hasSetThirdTexture = YES;
        [thirdInputFramebuffer lock];
    }
    else
    {
        fourthInputFramebuffer = newInputFramebuffer;
        [fourthInputFramebuffer lock];
    }
}

- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
{
    if (textureIndex == 0)
    {
        [super setInputSize:newSize atIndex:textureIndex];

        if (CGSizeEqualToSize(newSize, CGSizeZero))
        {
            hasSetFirstTexture = NO;
        }
    }
    else if (textureIndex == 1)
    {
        if (CGSizeEqualToSize(newSize, CGSizeZero))
        {
            hasSetSecondTexture = NO;
        }
    }
    else if (textureIndex == 2)
    {
        if (CGSizeEqualToSize(newSize, CGSizeZero))
        {
            hasSetThirdTexture = NO;
        }
    }
}

- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
    if (textureIndex == 0)
    {
        inputRotation = newInputRotation;
    }
    else if (textureIndex == 1)
    {
        inputRotation2 = newInputRotation;
    }
    else if (textureIndex == 2)
    {
        inputRotation3 = newInputRotation;
    }
    else
    {
        inputRotation4 = newInputRotation;
    }
}

- (CGSize)rotatedSize:(CGSize)sizeToRotate forIndex:(NSInteger)textureIndex;
{
    CGSize rotatedSize = sizeToRotate;

    GPUImageRotationMode rotationToCheck;
    if (textureIndex == 0)
    {
        rotationToCheck = inputRotation;
    }
    else if (textureIndex == 1)
    {
        rotationToCheck = inputRotation2;
    }
    else if (textureIndex == 2)
    {
        rotationToCheck = inputRotation3;
    }
    else
    {
        rotationToCheck = inputRotation4;
    }

    if (GPUImageRotationSwapsWidthAndHeight(rotationToCheck))
    {
        rotatedSize.width = sizeToRotate.height;
        rotatedSize.height = sizeToRotate.width;
    }

    return rotatedSize;
}

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
    // You can set up infinite update loops, so this helps to short circuit them
    if (hasReceivedFirstFrame && hasReceivedSecondFrame && hasReceivedThirdFrame)
    {
        return;
    }

    BOOL updatedMovieFrameOppositeStillImage = NO;

    if (textureIndex == 0)
    {
        hasReceivedFirstFrame = YES;
        firstFrameTime = frameTime;
        if (secondFrameCheckDisabled)
        {
            hasReceivedSecondFrame = YES;
        }
        if (thirdFrameCheckDisabled)
        {
            hasReceivedThirdFrame = YES;
        }
        if (fourthFrameCheckDisabled)
        {
            hasReceivedThirdFrame = YES;
        }

        if (!CMTIME_IS_INDEFINITE(frameTime))
        {
            if CMTIME_IS_INDEFINITE(secondFrameTime)
            {
                updatedMovieFrameOppositeStillImage = YES;
            }
        }
    }
    else if (textureIndex == 1)
    {
        hasReceivedSecondFrame = YES;
        secondFrameTime = frameTime;
        if (firstFrameCheckDisabled)
        {
            hasReceivedFirstFrame = YES;
        }
        if (thirdFrameCheckDisabled)
        {
            hasReceivedThirdFrame = YES;
        }
        if (fourthFrameCheckDisabled)
        {
            hasReceivedFourthFrame = YES;
        }

        if (!CMTIME_IS_INDEFINITE(frameTime))
        {
            if CMTIME_IS_INDEFINITE(firstFrameTime)
            {
                updatedMovieFrameOppositeStillImage = YES;
            }
        }
    }
    else if (textureIndex == 2)
    {
        hasReceivedThirdFrame = YES;
        thirdFrameTime = frameTime;
        if (firstFrameCheckDisabled)
        {
            hasReceivedFirstFrame = YES;
        }
        if (secondFrameCheckDisabled)
        {
            hasReceivedSecondFrame = YES;
        }
        if (fourthFrameCheckDisabled)
        {
            hasReceivedFourthFrame = YES;
        }

        if (!CMTIME_IS_INDEFINITE(frameTime))
        {
            if CMTIME_IS_INDEFINITE(firstFrameTime)
            {
                updatedMovieFrameOppositeStillImage = YES;
            }
        }
    }
    else
    {
        hasReceivedFourthFrame = YES;
        fourthFrameTime = frameTime;
        if (firstFrameCheckDisabled)
        {
            hasReceivedFirstFrame = YES;
        }
        if (secondFrameCheckDisabled)
        {
            hasReceivedSecondFrame = YES;
        }
        if (thirdFrameCheckDisabled)
        {
            hasReceivedThirdFrame = YES;
        }

        if (!CMTIME_IS_INDEFINITE(frameTime))
        {
            if CMTIME_IS_INDEFINITE(firstFrameTime)
            {
                updatedMovieFrameOppositeStillImage = YES;
            }
        }
    }

    // || (hasReceivedFirstFrame && secondFrameCheckDisabled) || (hasReceivedSecondFrame && firstFrameCheckDisabled)
    // 如果已经接收四个纹理输入或者是有效帧,则渲染
    if ((hasReceivedFirstFrame && hasReceivedSecondFrame && hasReceivedThirdFrame && hasReceivedFourthFrame) || updatedMovieFrameOppositeStillImage)
    {
        static const GLfloat imageVertices[] = {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f,
        };

        [self renderToTextureWithVertices:imageVertices textureCoordinates:[[self class] textureCoordinatesForRotation:inputRotation]];

        [self informTargetsAboutNewFrameAtTime:frameTime];

        hasReceivedFirstFrame = NO;
        hasReceivedSecondFrame = NO;
        hasReceivedThirdFrame = NO;
        hasReceivedFourthFrame = NO;
    }
}

@end
GPUImage:原始码对GPUImage进行剖析以及尝试 GPU图像 原始码对GPUImage进行剖析以及尝试 如果你有想法和建议,欢迎加群263556662交流。 GPUImageChromaKeyBlendFilter 立即下载

相关推荐

脑电分析:为什么大脑信号会“变同步”?——事件相关同步化与去同步化 (ERS/ERD) 全景解析

脑电分析中的事件相关同步化(ERS)和去同步化(ERD)是研究大脑动态节律的重要方法,反映特定任务下脑电频段能量的变化。ERD表示神经元活动分散(功率下降),提示脑区活跃处理信息;ERS则反映神经元同步(功率增强),常与静息状态相关。本文详解了ERS/ERD的生理机制、计算流程(包括基线校正和功率谱分析),并提供了Python实现示例,展示如何通过Welch法和STFT进行时频分析,生成ERD/ERS热力图。该技术广泛应用于运动想象脑机接口、癫痫检测等领域,为理解大脑功能状态提供了量化工具。

qq_32516809的博客 1395

OpenGL之GPUImage源码分析

在相机数据采集中,还有一些小的细节问题,比如相机前置与后置摄像头的左右镜像翻转问题。在前面讲到过,GPUImage 的纹理坐标原点是位于左上角的,所以使用 TEXTURE_NO_ROTATION 的纹理坐标实质上是将图像进行了上下翻转,两次调用TEXTURE_NO_ROTATION纹理坐标时,又将图像复原了,这也就可以解释为什么滤镜个数为偶数时,需要使用 mGLTextureFlipBuffer 纹理坐标将图像再进行一次翻转,而 mGLTextureBuffer 纹理坐标不需要了。

程序猿老樊的博客 776

红外图像和可见光图像异源图像配准问题研究

本文旨在研究一种具有高准确率和鲁棒性的融合图像障碍物检测技术,通过把红外和可见光图像进行图像配准和融合,获取高质量的异源融合图像,根据融合图像的特点采用有效的障碍物检测算法,将图像中的障碍物准确检出。......

G_redsky的博客 1万+

GPUImage源码分析与使用(一)

有丰富的输入组件,可以处理图片、纹理、视频、二进制数据、UIElement(UIView、CALayer),可以使用GPUImage拍照、处理纹理图片、给视频或拍摄中的视频添加滤镜、添加水印可以使用UIElement。支持对大图进行处理,GPU的纹理限制是4096*4096,对于超出限制的图片,GPUImage会压缩处理导致损失图片质量,CoreImage会把图片拆解成小图处理。可以传入字符串类型,也可以传入文件类型,比如以.vsh/.fsh/.glsl等为后缀等命名的文件。

程序猿老樊的博客 1123

合泰单片机HT32之keil5开发环境搭建(一)

1. 前言 这两天在准备合泰杯,但是总是感觉无从下手,因为合泰单片机的资料教程什么的非常少,不像stm32那样。而且听说要用合泰单片机的专用IDE,感觉当场被劝退了。后来经过查找资料,发现合泰单片机也有keil5的支持包,也就是说可以从库函数进行开发,不用从寄存器进行开发,但我找了好久,并没有找到教程,后来实在没办法,打算自己动手搭建环境,经过了大概两天的挣扎后,终于成功地搭建好了环境,也成功地点...

weixin_44713763的博客 8669

从仿真到器件:铌酸锂电光调制器Comsol建模避坑指南

本文详细介绍了铌酸锂电光调制器在Comsol中的建模全流程,涵盖晶体切向选择、材料参数配置、多物理场耦合等关键技术。通过实战案例和调试技巧,帮助工程师避开常见建模陷阱,提升仿真精度与效率,特别适用于高速光通信系统的器件设计与优化。

m2n3b4v5c6的博客 419

多重滤镜

UIImage *faceImage = [UIImage imageNamed:@"469453586_640.jpg"]; UIImageView *face = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, faceImage.size.width/2.0, faceImage.size.height/2.0)]; [fa

allanGold 700

保姆级教程:用R语言自动化处理FAERS季度数据(从文件合并到删除废弃Case)

本文提供了一份详细的R语言教程,指导如何自动化处理FAERS季度数据,包括文件合并和删除废弃Case。通过使用tidyverse、fs等R包,构建健壮的自动化流程,特别适合药物安全监测领域的数据分析师。教程涵盖环境准备、智能合并多季度数据、精准删除废弃Case等关键步骤,并提供了错误处理与日志记录的实用技巧。

weixin_42701915的博客 124

OpenGL 之 GPUImage 源码分析

GPUImage 是 iOS 上一个基于 OpenGL 进行图像处理的开源框架,后来有人借鉴它的想法实现了一个 Android 版本的 GPUImage ,本文也主要对 Android 版本的 GPUImage 进行分析。 概要 在 GPUImage 中既有对图像进行处理的,也有对相机内容进行处理的,这里主要以相机处理为例进行分析。 大致会分为三个部分: 相机数据的采集 Open...

音视频开发进阶 1325

从Palantir到AI时代:Forward Deployed Engineer模式的深度解析

《从Palantir到AI时代:FDE模式的创新与挑战》摘要:Palantir开创的前置部署工程师(FDE)模式正在成为AI创业公司的标配。该模式通过现场工程师深入了解客户需求,填补产品与实际应用间的鸿沟,颠覆了传统SaaS规模化路径。核心优势在于将定制化服务转化为产品发现机制,特别适合高度异质化的AI市场。成功关键在于平衡定制与标准化,通过合同价值增长、产品杠杆效应等独特指标衡量成效。FDE人才需要兼具领域洞察力与快速原型能力。这一模式表明,在AI等新兴领域,深入客户现场可能比单纯追求技术突破更能创造商业

老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 4534

企业微信自建应用全流程部署指南:从HTTPS到API调试

本文提供了一份详尽的企业微信自建应用部署指南,涵盖从HTTPS域名配置、Nginx反向代理到企业微信后台应用创建与API调试的全流程。核心在于构建一个符合企业微信安全要求的“可信”服务环境,并利用JupyterLab等工具进行高效调试,帮助企业快速完成内部系统与企业微信的集成。

weixin_29247219的博客 422

GPUImage源码解读(二十一)

GPUImageThreeInputFilter 可以接收三个帧缓存对象的输入。它的作用可以将三个帧缓存对象的输入合并成一个帧缓存对象的输出。它继承自GPUImageTwoInputFilter,与GPUImageTwoInputFilter类似,主要增加了第三个帧缓存对象处理的相关操作。 实例变量。主要增加了与第三个帧缓存对象相关的实例变量 “` @interface GPUImageT...

Philm_iOS的博客 398

Deep SHAP 深度学习模型的可解释性分析

Deep SHAP 算法是一种用于解释深度学习模型的技术, 该算法通过将每个特征的重要性与输出值相关联来进行解释。本博客对深度学习的模型可解释性进行了分析。

cnjs1994的博客 5119

GPUImage 源码分析

GPUImage源码解读 介绍 GitHub - cats-oss/android-gpuimage: Android filters based on OpenGL (idea from GPUImage for iOS) 做图片或者视频滤镜渲染,离不开 OpenGL,而在移动平台上最令人熟知的就是 GitHub - BradLarson/GPUImage2: GPUImage 2 is ...

crazy_jack 2173

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

iOS GPUImage研究总结

关于GPUImage 这里直接引用官方描述:GPUImage是使用GPU处理图像的、他可以对图片、实时画面、视频进行处理。他允许你自定义滤镜、支持iOS4.0。然而,目前缺乏核心形象的一些更高级的功能,比如面部检测。

Quinn's blog ! I'm glad to be here! 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

iOS GPUImage源码解读

前言 GPUImage是iOS上一个基于OpenGL进行图像处理的开源框架,内置大量滤镜,架构灵活,可以在其基础上很轻松地实现各种图像处理功能。本文主要向大家分享一下项目的核心架构、源码解读及使用心得。 GPUImage有哪些特性 丰富的输入组件 摄像头、图片、视频、OpenGL纹理、二进制数据、UIElement(UIView, CALayer) 大量现成的内置滤镜(4大类) 1). 颜...

majiakun1的专栏 3613

iOS开发——GPUImage源码解析

一、基本概念 GPUImage:一个开源的、基于openGL的图片或视频的处理框架,其本身内置了多达120多种常见的滤镜效果,并且支持照相机和摄像机的实时滤镜,并且能够自定义图像滤镜。同时也很方便在原有基础上加入自己的滤镜Filter,所有滤镜是基于opengl shader(着色器)实现的,所以滤镜效果图像处理是在GPU上实现的,处理效率比较高,在iPhone6及其以上手机,可以做到实时流...

weixin_30240349的博客 378

GPUImage源码解读(一)

导读: 系列文章会从结构到使用,细化到每一个变量, 使用方法全有对应 DEMO.也会有相对应的技术点扩展如(AVFoundation,OpenGL shader,CAEAGLLayer)等,目前是 Objective-C 版本的,后面会有Swift版本. GPUImage-Objective-C 官方源码 GPUImage-Swift 官方源码 GPUImage-Objective-C 添...

Philm_iOS的博客 802

c语言freeimage库文件,GPUImage源码解读之GLProgram

简述GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。其实是作者对OpenGL ES program的面向对象封装初始化- (id)initWithVertexShaderString:(NSString *)vShaderStringfragmentShaderString:(NSString *)fShaderString;- (id...

weixin_36176188的博客 303

GPUImage源码解读(二)

这篇文章主要是阅读GPUImage框架中的 GLProgram、GPUImageContext 两个重要类的源码。这两个类是 GPUImage 框架的基础,里面涉及的知识也有 OpenGL ES 基础 和 多线程 基础。以下是源码内容: GLProgram 一 GLProgram GLProgram专门处理OpenGL ES程序的创建等相关工作。 初始化方法,可以根据需要传入顶点着色...

Philm_iOS的博客 570

android 滤镜开源,Android_GPUImage 支持实时摄像头滤镜的GPUImage是iOS下一个开源的基于GPU的图像处理库 - 下载 - 搜珍网...

Android例子源码支持实时摄像头滤镜的GPUImage/Android例子源码支持实时摄像头滤镜的GPUImage/.gitignoreAndroid例子源码支持实时摄像头滤镜的GPUImage/library/Android例子源码支持实时摄像头滤镜的GPUImage/library/.classpathAndroid例子源码支持实时摄像头滤镜的GPUImage/library/.gitig...

weixin_36397146的博客 185

GPUImage源码解读之GLProgram

简述 GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。其实是作者对OpenGL ES program的面向对象封装 初始化 - (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderString:(NSString *)fS...

weixin_30346033的博客 169

GPUImage源码解读(二十四)

GPUImageLookupFilter GPUImageLookupFilter 是GPUImage中的颜色查找滤镜,在一般的相机应用中使用得最广泛,它的作用是通过颜色变换从而产生出新风格的图片,在philm项目中也有大量使用 LUT (Lookup Tables)即查找表 。LUT是个非常简单的数值转换表,不同的色彩输入数值“映射”到一套输出数值,用来改变图像的色彩。例如:红色在LUT中可...

Philm_iOS的博客 747

GPUImage源码解读(八)

GPUImageView 从名称就可以知道GPUImageView是GPUImage框架中显示图片相关的类。GPUImageView实现了GPUImageInput协议,从而可以知道它能够接受GPUImageFramebuffer的输入。因此,常常作为响应链的终端节点,用于显示处理后的帧缓存。 - 重写静态方法 返回 CAEAGLLayer GPUImageView 是UIView的子类...

Philm_iOS的博客 502

GPUImage源码解读(二十五)

#GPUImageView 结构说明 . ├── GPUImage.xcodeproj │   ├── project.pbxproj │   ├── project.xcworkspace ├── GPUImageMac.xcodeproj │   ├── project.pbxproj │  

Philm_iOS的博客 458

GPUImage源码解读(二十三)

GPUImageFilter GPUImageFilter 是GPUImage中很重要、很基础的类,它可以处理帧缓存对象的输入输出,但是对纹理并不添加任何特效,也就是说只是简单的让纹理通过。它更多的是作为其它滤镜的基类,一些具体的滤镜由它的子类去完成。同时它也只能处理单个帧缓存对象的输入,处理多个帧缓存对象的输入也是由它的子类去完成 向量定义 //在 GPUImage 中主要用到了3...

Philm_iOS的博客 485
上一篇: GPUImage源码解读(二十一)
下一篇: GPUImage源码解读(二十三)
Philm_iOS
博客等级 码龄8年 74粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值