CPUImageRGBFilter 实现
2024-09-11 21:21:41
参考自: https://github.com/BradLarson/GPUImage
GPUImageRGBFilter: Adjusts the individual RGB channels of an image
- red: Normalized values by which each color channel is multiplied. The range is from 0.0 up, with 1.0 as the default.
- green:
- blue:
对应的Shader:
varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform highp float redAdjustment; uniform highp float greenAdjustment; uniform highp float blueAdjustment; void main() { highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a); }
简单解释一下以上Shader.
uniform 声明为只读变量。
varying 声明为读写变量。
highp 为计算精度。这里为高精度。
textureCoordinate为对应的纹理坐标位置即(x,y)
inputImageTexture为输入的纹理图。
texture2D 取对应纹理图所在坐标的像素颜色。
所以整个算法很简单,就是将对应纹理图所在坐标的像素进行相应的 红绿蓝 权重调整。
权重的取值范围为[0,1]
根据以上Shader进行CPU代码转换。
#ifndef ClampToByte #define ClampToByte(v)(((unsigned) int(v)) < (255) ? (v) : (v < 0) ? int(0) : int(255)) #endif void CPUImageRGBFilter(unsigned char* Input, unsigned char* Output, int Width, int Height, int Stride, float redAdjustment = 1.0f, float greenAdjustment = 1.0f, float blueAdjustment = 1.0f) { int Channels = Stride / Width; ) return; int numberOfPixels = Width*Height; unsigned char* scanLineIn = Input; unsigned char* scanLineOut = Output; ; pixel < numberOfPixels; pixel++) { scanLineOut[] = ClampToByte(scanLineIn[] * redAdjustment); scanLineOut[] = ClampToByte(scanLineIn[] * greenAdjustment); scanLineOut[] = ClampToByte(scanLineIn[] * blueAdjustment); scanLineIn += Channels; scanLineOut += Channels; } }
转换后可进行建表优化。
即:
void CPUImageRGBFilter(unsigned char* Input, unsigned char* Output, int Width, int Height, int Stride, float redAdjustment = 1.0f, float greenAdjustment = 1.0f, float blueAdjustment = 1.0f) { int Channels = Stride / Width; ) return; unsigned ] = { }; unsigned ] = { }; unsigned ] = { }; ; pixel < ; pixel++) { AdjustMapR[pixel] = pixel*redAdjustment; AdjustMapG[pixel] = pixel*greenAdjustment; AdjustMapB[pixel] = pixel*blueAdjustment; } ; Y < Height; Y++) { unsigned char* scanLineOut = Output + (Y * Stride); unsigned char* scanLineIn = Input + (Y * Stride); ; X < Width; X++) { scanLineOut[] = AdjustMapR[scanLineIn[]]; scanLineOut[] = AdjustMapG[scanLineIn[]]; scanLineOut[] = AdjustMapB[scanLineIn[]]; scanLineIn += Channels; scanLineOut += Channels; } } }
代码比较简单,一看就明了。
待后续有时间,再通过simd指令集以及thread等方式进行改写。
最新文章
- Live555流媒体服务器编译(Windows下)
- 手机版本高于xcode,xcode的快速升级
- 新上市Lighthouse专用芯片TS3633规格介绍
- 调整static变量初始化顺序的一个办法
- DFS
- oracle LogMiner配置使用
- servlet跳转jsp
- Android学习总结——Service组件
- Javascript 获取窗口的大小和位置
- SQL Server调试常用参数
- 原生JS的Ajax
- Win 10 下 android studio显示 Intel haxm无法安装,以及VT-X和hyper-x的冲突问题
- C++中的常量函数
- Keras + LSTM 做回归demo
- 原来你离BAT只有一步之遥
- Java Observer接口和Observable类实现观察者模式
- 【HBase调优】Hbase万亿级存储性能优化总结
- Vijos1605 NOIP2008 提高组T4 双栈排序 BFS
- 以太坊难度炸弹是什么?极大抑制矿工继续以POW方式挖矿!
- java深浅拷贝