diff --git a/filter.c b/filter.c index 0eb2dfc..8c0379c 100644 --- a/filter.c +++ b/filter.c @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { // Define allowable filters - char *filters = "bgrsivtmdGoB:"; + char *filters = "bgrsivtmdGoPB:"; // Allocate filter array char *filterArr = (char *)malloc((argc - 2) * sizeof(char)); @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) printf(" -B Adjust brightness\n"); printf(" -G Glow\n"); printf(" -o Oil paint\n"); + printf(" -P Pixelate (mosaic effect)\n"); printf(" -m Show this menu\n\n"); free(filterArr); return 0; @@ -60,7 +61,7 @@ int main(int argc, char *argv[]) if (argc < optind + 2) { printf("Usage: ./filter [flag] infile outfile\n"); - printf("Filters: -g (grayscale), -s (sepia), -r (reflect), -b (blur), -i (invert), -v (vignette), -G (glow), -t (threshold), -d (edge detection), -o (oil paint), -B (brightness)\n"); + printf("Filters: -g (grayscale), -s (sepia), -r (reflect), -b (blur), -i (invert), -v (vignette), -G (glow), -t (threshold), -d (edge detection), -o (oil paint), -P (pixelate), -B (brightness)\n"); free(filterArr); return 3; } @@ -147,6 +148,9 @@ int main(int argc, char *argv[]) oilpaint(height, width, image); break; + case 'P': // Pixelate + pixelate(height, width, image); + break; default: printf("Unknown filter: %c\n", filterArr[i]); free_image(&img); diff --git a/helpers.c b/helpers.c index fc2d198..0093e4b 100644 --- a/helpers.c +++ b/helpers.c @@ -423,3 +423,42 @@ void oilpaint(int height, int width, RGBTRIPLE image[height][width]){ free(copy[i]); free(copy); } + +// Pixelate filter +void pixelate(int height, int width, RGBTRIPLE image[height][width]){ + int blockSize = 8; + if (width > 1000 || height > 1000) { + blockSize = 16; + } else if (width > 500 || height > 500) { + blockSize = 12; + } + for (int blockY = 0; blockY < height; blockY += blockSize){ + for (int blockX = 0; blockX < width; blockX += blockSize){ + int blockEndY = min(blockY + blockSize, height); + int blockEndX = min(blockX + blockSize, width); + + long sumRed = 0, sumGreen = 0, sumBlue = 0; + int pixelCount = 0; + + for (int y = blockY; y < blockEndY; y++){ + for (int x = blockX; x < blockEndX; x++){ + sumRed += image[y][x].rgbtRed; + sumGreen += image[y][x].rgbtGreen; + sumBlue += image[y][x].rgbtBlue; + pixelCount++; + } + } + uint8_t avgRed = (uint8_t)(sumRed / pixelCount); + uint8_t avgGreen = (uint8_t)(sumGreen / pixelCount); + uint8_t avgBlue = (uint8_t)(sumBlue / pixelCount); + + for (int y = blockY; y < blockEndY; y++){ + for (int x = blockX; x < blockEndX; x++){ + image[y][x].rgbtRed = avgRed; + image[y][x].rgbtGreen = avgGreen; + image[y][x].rgbtBlue = avgBlue; + } + } + } + } +} \ No newline at end of file diff --git a/helpers.h b/helpers.h index 13923ad..abd4ae9 100644 --- a/helpers.h +++ b/helpers.h @@ -37,4 +37,6 @@ void vignette(int height, int width, RGBTRIPLE image[height][width]); void glow(int height, int width, RGBTRIPLE image[height][width]); // Oil Paint filter void oilpaint(int height, int width, RGBTRIPLE image[height][width]); +// Pixelate filter +void pixelate(int height, int width, RGBTRIPLE image[height][width]); #endif