diff --git a/filter.c b/filter.c index cb1c565..117df8a 100644 --- a/filter.c +++ b/filter.c @@ -7,7 +7,7 @@ int main(int argc, char *argv[]) { // Define allowable filters - char *filters = "bgrsivtdGB:"; + char *filters = "bgrsivtdGoB:"; char filterArr[argc-3]; @@ -146,6 +146,10 @@ int main(int argc, char *argv[]) case 'G': glow(height, width, image); break; + case 'o': + oilpaint(height, width, image); + break; + default: printf("Unknown filter: %c\n", filterArr[i]); free(image); diff --git a/filter.exe b/filter.exe new file mode 100644 index 0000000..fe12402 Binary files /dev/null and b/filter.exe differ diff --git a/helpers.c b/helpers.c index 5a7d2ef..fc2d198 100644 --- a/helpers.c +++ b/helpers.c @@ -3,6 +3,11 @@ #include #include #include "bmp.h" +#include + +#define LEVELS 16 +#define RADIUS 8 + int min(int a,int b){ if(ab) return a; return b; } + void grayscale(int height, int width, RGBTRIPLE image[height][width]){ for(int i = 0; i < height; i++){ @@ -356,3 +362,64 @@ void glow(int height, int width, RGBTRIPLE image[height][width]) free(original); free(blurred); } +// Oil Paint filter +void oilpaint(int height, int width, RGBTRIPLE image[height][width]){ + RGBTRIPLE **copy = malloc(height * sizeof(RGBTRIPLE *)); + for (int i = 0; i < height; i++){ + copy[i] = malloc(width * sizeof(RGBTRIPLE)); + for (int j = 0; j < width; j++){ + copy[i][j] = image[i][j]; + } + } + // logic + for (int i = 0; i < height; i++){ + for (int j = 0; j < width; j++){ + int intensityCount[LEVELS]; + long sumRed[LEVELS], sumGreen[LEVELS], sumBlue[LEVELS]; + memset(intensityCount, 0, sizeof(intensityCount)); + memset(sumRed, 0, sizeof(sumRed)); + memset(sumGreen, 0, sizeof(sumGreen)); + memset(sumBlue, 0, sizeof(sumBlue)); + + // Analyze neighborhood + for (int di = -RADIUS; di <= RADIUS; di++){ + for (int dj = -RADIUS; dj <= RADIUS; dj++){ + int ni = i + di; + int nj = j + dj; + if (ni < 0 || ni >= height || nj < 0 || nj >= width) + continue; + + RGBTRIPLE pixel = copy[ni][nj]; + int intensity = ((pixel.rgbtRed + pixel.rgbtGreen + pixel.rgbtBlue) / 3) * LEVELS / 256; + if (intensity >= LEVELS) + intensity = LEVELS - 1; + + intensityCount[intensity]++; + sumRed[intensity] += pixel.rgbtRed; + sumGreen[intensity] += pixel.rgbtGreen; + sumBlue[intensity] += pixel.rgbtBlue; + } + } + + int dominant = 0, maxCount = 0; + for (int k = 0; k < LEVELS; k++){ + if (intensityCount[k] > maxCount){ + maxCount = intensityCount[k]; + dominant = k; + } + } + if (maxCount > 0){ + int newRed = sumRed[dominant] / maxCount; + int newGreen = sumGreen[dominant] / maxCount; + int newBlue = sumBlue[dominant] / maxCount; + + image[i][j].rgbtRed = (newRed / 32) * 32; + image[i][j].rgbtGreen = (newGreen / 32) * 32; + image[i][j].rgbtBlue = (newBlue / 32) * 32; + } + } + } + for (int i = 0; i < height; i++) + free(copy[i]); + free(copy); +} diff --git a/helpers.h b/helpers.h index 0acb499..13923ad 100644 --- a/helpers.h +++ b/helpers.h @@ -35,4 +35,6 @@ void vignette(int height, int width, RGBTRIPLE image[height][width]); // Glow filter void glow(int height, int width, RGBTRIPLE image[height][width]); +// Oil Paint filter +void oilpaint(int height, int width, RGBTRIPLE image[height][width]); #endif diff --git a/input.bmp b/in.bmp similarity index 100% rename from input.bmp rename to in.bmp diff --git a/out.bmp b/out.bmp index 6cc4070..ff48ce3 100644 Binary files a/out.bmp and b/out.bmp differ