I'm trying to create a Gaussian blur in C using SDL.
Here is my function:
We admit that the param surface
is a grayscale image (that's why i only use the r
).
SDL_Surface* gaussian_blur(SDL_Surface* surface) {
int w = surface->w;
int h = surface->h;
SDL_Surface* res = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Uint8 r = 0;
for (int i = -2; i <= 2; i++) {
for (int j = -2; j <= 2; j++) {
Uint32 pixel = get_pixel(surface, x+i, y+j);
double weight = core[i+2][j+2];
r += pixel*weight;
}
}
Uint32 nPixel = SDL_MapRGB(res->format, r, r, r);
put_pixel(res, x, y, nPixel);
}
}
free_surface(surface);
return res;
}
My core is defined as it :
double core[KERNEL_SIZE][KERNEL_SIZE] = {
{1.0/273.0, 4.0/273.0, 7.0/273.0, 4.0/273.0, 1.0/273.0},
{4.0/273.0, 16.0/273.0, 26.0/273.0, 16.0/273.0, 4.0/273.0},
{7.0/273.0, 26.0/273.0, 41.0/273.0, 26.0/273.0, 7.0/273.0},
{4.0/273.0, 16.0/273.0, 26.0/273.0, 16.0/273.0, 4.0/273.0},
{1.0/273.0, 4.0/273.0, 7.0/273.0, 4.0/273.0, 1.0/273.0}
};
Uint32 get_pixel(SDL_Surface* surface, int x, int y) {
int w = surface->w;
int h = surface->h;
if (surface != NULL && x >= 0 && x < w && y >= 0 && y < h) {
Uint32* pixels = (Uint32*)surface->pixels;
return pixels[y * w + x];
}
return 0;
}
void put_pixel(SDL_Surface* surface, int x, int y, Uint32 pixel) {
int w = surface->w;
int h = surface->h;
if (surface != NULL && x >= 0 && x < w && y >= 0 && y < h) {
Uint32* pixels = (Uint32*)surface->pixels;
pixels[y * w + x] = pixel;
}
}
The picture is the result of the function : Result of the function
I've searched on different sites but I can't find anything that could help me.
I can't use MATHLAB or OpenCV. I'm only allowed to use SDL
If anyone has any ideas on how to go about it, I'd love to hear from you.
My get_pixel give me all the color (r, g and b). So i have just to apply a mask (& 0xFF) to have the right color.
There is the correction :
Uint8 pixel_color(SDL_Surface* surface, int w, int h, int x, int y) {
Uint8 r = 0;
for (int i = -2; i <= 2; i++) {
for (int j = -2; j <= 2; j++) {
Uint32 pixel = get_pixel(surface, x+i, y+j);
Uint8 pixel_color = pixel & 0xFF; //HERE
double weight = core[i+2][j+2];
int nX = x+i, nY = y+j;
if (nX >= 0 && nX < w && nY >= 0 && nY < h)
r += pixel_color*weight;
else
r += weight*255;
}
}
return r;
}
SDL_Surface* gaussian_blur(SDL_Surface* surface) {
int w = surface->w;
int h = surface->h;
SDL_Surface* res = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Uint8 color = pixel_color(surface, w, h, x, y);
Uint32 nPixel = SDL_MapRGB(res->format, color, color, color);
put_pixel(res, x, y, nPixel);
}
}
free_surface(surface);
return res;
}