152 lines
4.6 KiB
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;
|
|
} |