Skip to content

Commit 6d8925a

Browse files
Merge pull request #31 from Satvik-Singh192/glow-filter
feat: add glow filter
2 parents 6af2202 + b4558b2 commit 6d8925a

File tree

5 files changed

+99
-5
lines changed

5 files changed

+99
-5
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ The result is clamped between 0 and 255 and replaces the original pixel value. T
177177

178178
---
179179

180+
### 8.) The Glow Algorithm
181+
182+
The “Glow” filter gives bright regions of an image a soft, luminous halo, similar to a cinematic bloom effect. This filter works by blending the original image with a blurred version of itself.
183+
184+
The algorithm first creates a copy of the image and applies a mild box blur (using a smaller kernel than the main blur filter) to it. Then, for each pixel, the final color values are calculated by combining the original pixel's color with the new blurred pixel's color using a weighted average:
185+
186+
- `finalRed = 0.7 * originalRed + 0.3 * blurredRed`
187+
- `finalGreen = 0.7 * originalGreen + 0.3 * blurredGreen`
188+
- `finalBlue = 0.7 * originalBlue + 0.3 * blurredBlue`
189+
190+
The resulting values are rounded to the nearest integer and capped at 255. This process brightens the image and causes the light to "bleed" from bright areas into darker ones, creating a soft, luminous effect.
191+
180192
### Usage
181193

182194
To apply a filter via command-line:
@@ -186,6 +198,13 @@ To apply a filter via command-line:
186198
- `b`: blur
187199
- `i`: invert
188200
- `v`: vignette
201+
- `G`: glow
202+
- `t`: threshold
203+
- `d`: edge detection
204+
- `B <value>`: brightness
205+
206+
Example for glow:
207+
./filter -G input.bmp output.bmp
189208

190209
For vignette:
191210
```

filter.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
int main(int argc, char *argv[])
88
{
99
// Define allowable filters
10-
char *filters = "bgrsivtdB:";
10+
char *filters = "bgrsivtdGB:";
1111

1212

1313
char filterArr[argc-3];
@@ -133,7 +133,6 @@ int main(int argc, char *argv[])
133133
case 't':
134134
threshold(height, width, image);
135135
break;
136-
137136
case 'd': // Edge Detection
138137
detect_edges(height, width, image);
139138
break;
@@ -144,6 +143,9 @@ int main(int argc, char *argv[])
144143
brightness(height, width, image, brightness_value);
145144
break;
146145
}
146+
case 'G':
147+
glow(height, width, image);
148+
break;
147149
default:
148150
printf("Unknown filter: %c\n", filterArr[i]);
149151
free(image);
@@ -179,4 +181,4 @@ int main(int argc, char *argv[])
179181
fclose(inptr);
180182
fclose(outptr);
181183
return 0;
182-
}
184+
}

filter.exe

-54.7 KB
Binary file not shown.

helpers.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "helpers.h"
22
#include <stdint.h>
33
#include <stdlib.h>
4+
#include <math.h>
45
#include "bmp.h"
56
int min(int a,int b){
67
if(a<b) return a;
@@ -283,4 +284,75 @@ void detect_edges(int height, int width, RGBTRIPLE image[height][width])
283284
for (int i = 0; i < height; i++)
284285
free(copy[i]);
285286
free(copy);
286-
}
287+
}
288+
void glow(int height, int width, RGBTRIPLE image[height][width])
289+
{
290+
// Step 1: make a copy of the original
291+
RGBTRIPLE **original = malloc(height * sizeof(RGBTRIPLE *));
292+
RGBTRIPLE **blurred = malloc(height * sizeof(RGBTRIPLE *));
293+
for (int i = 0; i < height; i++)
294+
{
295+
original[i] = malloc(width * sizeof(RGBTRIPLE));
296+
blurred[i] = malloc(width * sizeof(RGBTRIPLE));
297+
for (int j = 0; j < width; j++)
298+
{
299+
original[i][j] = image[i][j];
300+
}
301+
}
302+
303+
// Step 2: apply a *mild* blur to copy (smaller kernel)
304+
int kernelSize = 11;
305+
int offset = kernelSize / 2;
306+
307+
for (int i = 0; i < height; i++)
308+
{
309+
for (int j = 0; j < width; j++)
310+
{
311+
int sumRed = 0, sumGreen = 0, sumBlue = 0, count = 0;
312+
313+
for (int ki = -offset; ki <= offset; ki++)
314+
{
315+
for (int kj = -offset; kj <= offset; kj++)
316+
{
317+
int ni = i + ki, nj = j + kj;
318+
if (ni >= 0 && ni < height && nj >= 0 && nj < width)
319+
{
320+
sumRed += original[ni][nj].rgbtRed;
321+
sumGreen += original[ni][nj].rgbtGreen;
322+
sumBlue += original[ni][nj].rgbtBlue;
323+
count++;
324+
}
325+
}
326+
}
327+
328+
blurred[i][j].rgbtRed = sumRed / count;
329+
blurred[i][j].rgbtGreen = sumGreen / count;
330+
blurred[i][j].rgbtBlue = sumBlue / count;
331+
}
332+
}
333+
334+
// Step 3: blend original + blurred to produce glow
335+
for (int i = 0; i < height; i++)
336+
{
337+
for (int j = 0; j < width; j++)
338+
{
339+
float blend = 0.3; // glow intensity
340+
int newRed = (1 - blend) * original[i][j].rgbtRed + blend * blurred[i][j].rgbtRed;
341+
int newGreen = (1 - blend) * original[i][j].rgbtGreen + blend * blurred[i][j].rgbtGreen;
342+
int newBlue = (1 - blend) * original[i][j].rgbtBlue + blend * blurred[i][j].rgbtBlue;
343+
344+
image[i][j].rgbtRed = min(255, newRed);
345+
image[i][j].rgbtGreen = min(255, newGreen);
346+
image[i][j].rgbtBlue = min(255, newBlue);
347+
}
348+
}
349+
350+
// Step 4: cleanup
351+
for (int i = 0; i < height; i++)
352+
{
353+
free(original[i]);
354+
free(blurred[i]);
355+
}
356+
free(original);
357+
free(blurred);
358+
}

helpers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ void brightness(int height, int width, RGBTRIPLE image[height][width], int value
3333
// Vignette filter
3434
void vignette(int height, int width, RGBTRIPLE image[height][width]);
3535

36-
36+
// Glow filter
37+
void glow(int height, int width, RGBTRIPLE image[height][width]);
3738
#endif

0 commit comments

Comments
 (0)