如何修改GPUImageGaussianSelectiveBlurFilter以在矩形而不是圆上操作?

时间:2012-09-04 05:45:21

标签: iphone ios instagram gpuimage

我已经使用了GPUImage框架来获得类似于Instagram应用程序的模糊效果,在那里我已经制作了从照片库中获取图片的视图,然后我对其进行了设置。

其中一个效果是选择性模糊效果,其中只有一小部分图像清晰,其余部分模糊。 GPUImageGaussianSelectiveBlurFilter选择图像的圆形部分不模糊。

如何更改此项以使尖锐区域成为矩形?

2 个答案:

答案 0 :(得分:3)

因为Gill的回答并不完全正确,而且由于这似乎一遍又一遍地被问到,所以我将澄清上述评论。

默认情况下,选择性模糊的片段着色器具有以下代码:

 varying highp vec2 textureCoordinate;
 varying highp vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2; 

 uniform lowp float excludeCircleRadius;
 uniform lowp vec2 excludeCirclePoint;
 uniform lowp float excludeBlurSize;
 uniform highp float aspectRatio;

 void main()
 {
     lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);
     lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);

     highp vec2 textureCoordinateToUse = vec2(textureCoordinate2.x, (textureCoordinate2.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
     highp float distanceFromCenter = distance(excludeCirclePoint, textureCoordinateToUse);

     gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeCircleRadius - excludeBlurSize, excludeCircleRadius, distanceFromCenter));
 }

此片段着色器从原始清晰图像和图像的高斯模糊版本中获取像素颜色值。然后根据最后三行的逻辑将它们混合在一起。

这些线的第一行和第二行计算从指定的中心坐标(默认为标准化坐标中的(0.5,0.5)到图像的死点)到当前像素坐标的距离。最后一行使用smoothstep() GLSL函数,当距离中心点的距离在两个阈值之间,内部清晰圆圈和外部完全模糊圆圈之间行进时,在0和1之间平滑插值。 mix()运算符然后从smoothstep()获取输出,并在模糊和鲜明的颜色像素颜色之间淡入淡出以产生适当的输出。

如果您只是想修改它以生成方形而不是圆形,则需要调整片段着色器中的两条中心线,使距离基于线性X或Y坐标,而不是与毕达哥拉斯距离的距离。中心点。要执行此操作,请将着色器更改为:

 varying highp vec2 textureCoordinate;
 varying highp vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2; 

 uniform lowp float excludeCircleRadius;
 uniform lowp vec2 excludeCirclePoint;
 uniform lowp float excludeBlurSize;
 uniform highp float aspectRatio;

 void main()
 {
     lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);
     lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);

     highp vec2 textureCoordinateToUse = vec2(textureCoordinate2.x, (textureCoordinate2.y * aspectRatio + 0.5 - 0.5 * aspectRatio));

     textureCoordinateToUse = abs(excludeCirclePoint - textureCoordinateToUse);
     highp float distanceFromCenter = max(textureCoordinateToUse.x, textureCoordinateToUse.y);

     gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeCircleRadius - excludeBlurSize, excludeCircleRadius, distanceFromCenter));
 }

Gill提到的线条只是过滤器的输入参数,根本不能控制其圆度。

我进一步修改这个以产生一个通用的矩形形状作为读者的练习,但这应该为你如何做到这一点提供了一个基础,并对这个着色器中的线做了更多的解释。

答案 1 :(得分:0)

是吗......矩形效果的代码就在这两行

blurFilter = [[GPUImageGaussianSelectiveBlurFilter alloc] init];
        [(GPUImageGaussianSelectiveBlurFilter*)blurFilter      setExcludeCircleRadius:80.0/320.0];
        [(GPUImageGaussianSelectiveBlurFilter*)blurFilter setExcludeCirclePoint:CGPointMake(0.5f, 0.5f)];
       // [(GPUImageGaussianSelectiveBlurFilter*)blurFilter setBlurSize:0.0f];            [(GPUImageGaussianSelectiveBlurFilter*)blurFilter setAspectRatio:0.0f];