Last week i was having fun with OpenGL(in fact QGL) and creating some interesting effects with it like edge detection, embossing and sharpening. So i decided to work with GLSL(OpenGL Shading Language) and create the same effects using Fragment Shaders(yeah hardware accelerated effects).
So i used QGLShaderProgam that allows me create Fragment shaders in a Qt Way(tm). Initially i create two filters the first one was sharpening and the second was edge detection. Both work in a same way(with little modifications), applying a matrix convolution in the image.
The matrix convolution used in sharpening is:
0 -1 0
-1 5 -1
0 -1 0
And the matrix convolution used in edge dection is:
-1 -1 -1
-1 8 -1
-1 -1 -1
Below you can see the fragment shader used in sharpening.
uniform sampler2D sampler;
uniform vec2 offset[9];
uniform int kernel[9];
void main()
{
vec4 sum = vec4(0.0);
int i;
for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];
}
gl_FragColor = sum;
}
The shader used in edge is almost the same
uniform sampler2D sampler;
uniform vec2 offset[9];
uniform int kernel[9];
void main()
{
vec4 sum = vec4(0.0);
int i;
for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];
}
sum += 0.51;
gl_FragColor = sum;
}
The original image used in my experiments can be seen below:

The result of sharpening filter is:

Yeah we have a little bit improvement on the image.
And the result of edge filter is:

The embossing filter is a little bit complicated as you can see:
uniform sampler2D sampler;
uniform vec2 offset[9];
uniform int kernel[9];
void main()
{
vec4 sum = vec4(0.0);
int i = 0;
for( i = 0; i < 9; i++) {
vec4 color_tmp = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
float h = (color_tmp.x + color_tmp.y + color_tmp.z + color_tmp.w)/4.0;
if (h > 1)
h = 1.0;
if (h < 0)
h = 0.0;
vec4 color = vec4(h, h, h, h);
sum.x += color.x * kernel[i];
}
sum.x /= 1.0;
sum.x += 0.51;
if (sum.x > 1)
sum.x = 1;
if (sum.x < 0)
sum.x = 0;
gl_FragColor = vec4(sum.x, sum.x, sum.x, 1);
}
And the result is:

Qt already do OpenGL accelerated filters in QGraphicsEffects classes(look in qt_top_dir/src/opengl/qglpixmapfilter*) it is not anything new but it is interesting use it in others KDE application like krita filters
.