美图秀秀滤镜之亮度调整
图像的亮度, 指的是图像像素的强度, 黑色为最暗, 白色为最亮, 在ios中黑色用0来表示, 白色用1来表示.一个像素, 基本上是用RGB三个颜色分量来表示的. R(0-1), G(0-1),B(0-1).
亮度调整有多种计算方法,效果并不完全相同,在颜色的表示方法中, HSL(L)表示法就是:色相(hue)、饱和度(saturation)、亮度(lightness),改变其中的L值就可以调整图象的亮度,但效果显得比较生硬。
PhotoShop和GPUImage中采用的就是另外一种方法就是把图象每个点颜色的RGB分量分别加上亮度调整值,这种效果相对比较柔和。下面是顶点着色器和片段着色器代码(这些代码运行于GPU中)。
顶点着色
attribute vec4 position; //输入顶点位置属性 attribute vec4 inputTextureCoordinate;//输入纹理位置属性 varying vec2 textureCoordinate;//输出给片段着色器的纹理位置 void main() { gl_Position = position;//输出给片段着色器的顶点位置 textureCoordinate = inputTextureCoordinate.xy;//告诉片段着色器,顶点着色器正在处理的像素点。 }
片段着色
varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture;//输入的纹理图片。也就是我们要处理的图片 uniform lowp float brightness;//亮度值,我们在程序中可以调整的。 void main() { lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);//输入图片的纹理颜色 gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);//像素着色颜色。将每个像素的RGB分量与亮度值相加,得到心的像素颜色。即算法实现 }
在我的美图秀秀中,使用的是上述算法,而官方版不是
使用GPUImage的GPUImageBrightnessFilter来实现图像的亮度调整。
具体应用
1.在GPUImageBrightnessFilter中首先初始化该滤镜
GPUImageBrightnessFilter *filter = [[GPUImageBrightnessFilter alloc] init];
2.设置亮度值。该亮度值通过滑动UISlider来改变
filter.brightness = value;
3.设置亮度调整范围为整张图像
[filter forceProcessingAtSize:image.size];
4.设置输入图像纹理
GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];
[pic addTarget:filter];
5.处理图像
[pic processImage];
[filter useNextFrameForImageCapture];
6.获取处理后的图像
return [filter imageFromCurrentFramebuffer];
+ (UIImage *)changeValueForBrightnessFilter:(float)value image:(UIImage *)image; { GPUImageBrightnessFilter *filter = [[GPUImageBrightnessFilter alloc] init]; filter.brightness = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
附录
在GPUImageBrightnessFilter的init方法中,设置了默认的亮度为0
- (id)init; { if (!(self = [super initWithFragmentShaderFromString:kGPUImageBrightnessFragmentShaderString])) { return nil; } brightnessUniform = [filterProgram uniformIndex:@"brightness"]; self.brightness = 0.0; return self; }
setBrightness方法调整图像的亮度值,_brightness为输入的亮度值,在顶点着色器中uniform float brightness与brightnessUniform = [filterProgram uniformIndex:@"brightness"]对应,必须名字相同
- (void)setBrightness:(CGFloat)newValue; { _brightness = newValue; [self setFloat:_brightness forUniform:brightnessUniform program:filterProgram]; }
下面我们预览一下效果