CS50_Labs/Lab4/filter/helpers.c

152 lines
4.6 KiB
C

#include "helpers.h"
#include "math.h"
#include <stdlib.h>
#include <stdio.h>
int pix_round(double input);
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
double avg;
//loop through all rows
for (int i = 0; i < height; i++)
{
//loop through all columns
for (int j = 0; j < width; j++)
{
//calculate average from RGB and set RGB to it
avg = (image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed) / 3.0;
avg = pix_round(round(avg));
image[i][j].rgbtBlue = avg;
image[i][j].rgbtGreen = avg;
image[i][j].rgbtRed = avg;
}
}
return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
//loop through all rows
for (int i = 0; i < height; i++)
{
//loop through all columns
for (int j = 0; j < width; j++)
{
//save original RGB values
int originalBlue = image[i][j].rgbtBlue;
int originalGreen = image[i][j].rgbtGreen;
int originalRed = image[i][j].rgbtRed;
//calculate sepia RGB values
double sepiaRed = 0.393 * originalRed + 0.769 * originalGreen + 0.189 * originalBlue;
double sepiaGreen = 0.349 * originalRed + 0.686 * originalGreen + 0.168 * originalBlue;
double sepiaBlue = 0.272 * originalRed + 0.534 * originalGreen + 0.131 * originalBlue;
//round sepia values
sepiaBlue = pix_round(round(sepiaBlue));
sepiaGreen = pix_round(round(sepiaGreen));
sepiaRed = pix_round(round(sepiaRed));
//change image to sepia RGB
image[i][j].rgbtBlue = sepiaBlue;
image[i][j].rgbtGreen = sepiaGreen;
image[i][j].rgbtRed = sepiaRed;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
//loop through all rows
for (int i = 0; i < height; i++)
{
//loop through columns to middle
for (int j = 0; j < (width / 2); j++)
{
//create buffer to as temp store for RGB value, switch from right to left
RGBTRIPLE buffer = image[i][j];
image[i][j] = image[i][width - (j + 1)];
image[i][width - (j + 1)] = buffer;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE buffer[height][width];
// loops through all rows
for (int i = 0; i < height; i++)
{
//loops through all columns
for (int j = 0; j < width; j++)
{
//sets initial variable values to zero
double avgGreen = 0;
double avgBlue = 0;
double avgRed = 0;
int counter = 0;
//loop through all row offsets
for (int row_offset = -1; row_offset <= 1; row_offset++)
{
//loop through all col offsets
for (int col_offset = -1; col_offset <= 1; col_offset++)
{
int y = i + row_offset;
int x = j + col_offset;
// checks if offseted values are within the image coordinates
if (y >= 0 && y < height && x >= 0 && x < width)
{
// adds current RGB values to avgsum + increases counter
avgGreen = avgGreen + image[y][x].rgbtGreen;
avgBlue = avgBlue + image[y][x].rgbtBlue;
avgRed = avgRed + image[y][x].rgbtRed;
counter++;
}
}
}
// calculates and rounds avg RGB values
avgGreen = pix_round(round(avgGreen / counter));
avgBlue = pix_round(round(avgBlue / counter));
avgRed = pix_round(round(avgRed / counter));
//sets new RGB values to buffer
buffer[i][j].rgbtBlue = avgBlue;
buffer[i][j].rgbtGreen = avgGreen;
buffer[i][j].rgbtRed = avgRed;
}
}
//copying data from buffer back to image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtBlue = buffer[i][j].rgbtBlue;
image[i][j].rgbtGreen = buffer[i][j].rgbtGreen;
image[i][j].rgbtRed = buffer[i][j].rgbtRed;
}
}
return;
}
int pix_round(double input)
{
if (input >= 255)
{
input = 255;
}
else if (input <= 0)
{
input = 0;
}
return input;
}