Skip to content

Instantly share code, notes, and snippets.

@themattmcguire
Last active June 12, 2020 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save themattmcguire/1ee1a683fe2e22ff1b7b4ef8cebe120b to your computer and use it in GitHub Desktop.
Save themattmcguire/1ee1a683fe2e22ff1b7b4ef8cebe120b to your computer and use it in GitHub Desktop.
#include "helpers.h"
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++) //outer loop for rows
{
for (int j = 0; j < width; j++) //inner loop for each pixel
{
//determine average of the values of Red, Green, & Blue
int avg = (image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed) / 3;
//adjust all three values to the average
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])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
float newred = image[i][j].rgbtRed * .393 + image[i][j].rgbtGreen * .769 + image[i][j].rgbtBlue * .189;
float newgreen = image[i][j].rgbtRed * .349 + image[i][j].rgbtGreen * .686 + image[i][j].rgbtBlue * .168;
float newblue = image[i][j].rgbtRed * .272 + image[i][j].rgbtGreen * .534 + image[i][j].rgbtBlue * .131;
if (newred > 255)
{
newred = 255;
}
if (newgreen > 255)
{
newgreen = 255;
}
if (newblue > 255)
{
newblue = 255;
}
image[i][j].rgbtRed = (int) newred;
image[i][j].rgbtGreen = (int) newgreen;
image[i][j].rgbtBlue = (int) newblue;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
int half = width / 2;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < half; j++)
{
RGBTRIPLE placeholder = image[i][j];
image[i][j] = image[i][width - j];
image[i][width - j] = placeholder;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
//create a copy of the image from which to draw pixel values
RGBTRIPLE copy[height][width];
for (int a = 0; a < height; a++){
for (int b = 0; b < width; b++){
copy[a][b] = image[a][b];
}
}
//iterate over each pixel, drawing values from surrounding pixels
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//if pixel is a top left corner
if (i == 0 && j == 0){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i][j + 1].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 4;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 4;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 4;
}
//if pixel is a top right corner
else if (i == 0 && j == (width - 1)){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i + 1][j].rgbtRed) / 4;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i + 1][j].rgbtGreen) / 4;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i + 1][j].rgbtBlue) / 4;
}
//if pixel is a bottom left corner
else if (i == (height - 1) && j == 0){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i][j + 1].rgbtRed) / 4;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i][j + 1].rgbtGreen) / 4;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i][j + 1].rgbtBlue) / 4;
}
//if pixel is a bottom right corner
else if (i == (height - 1) && j == width){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i - 1][j - 1].rgbtRed + copy[i - 1][j].rgbtRed + copy[i][j - 1].rgbtRed) / 4;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i - 1][j - 1].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i][j - 1].rgbtGreen) / 4;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i - 1][j - 1].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i][j - 1].rgbtBlue) / 4;
}
//if pixel touches the top
else if (i == 0){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i][j + 1].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 6;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 6;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 6;
}
//if pixel touches the left
else if (j == 0){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i][j + 1].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 6;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 6;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 6;
}
//if pixel touches the right
else if (j == (width - 1)){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i - 1][j - 1].rgbtRed + copy[i - 1][j].rgbtRed + copy[i][j - 1].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i + 1][j].rgbtRed) / 6;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i - 1][j - 1].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i + 1][j].rgbtGreen) / 6;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i - 1][j - 1].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i + 1][j].rgbtBlue) / 6;
}
//if pixel touches the bottom
else if (i == (height - 1)){
image[i][j].rgbtRed = (copy[i][j].rgbtRed + copy[i - 1][j - 1].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i][j - 1].rgbtRed + copy[i][j + 1].rgbtRed) / 6;
image[i][j].rgbtGreen = (copy[i][j].rgbtGreen + copy[i - 1][j - 1].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i][j + 1].rgbtGreen) / 6;
image[i][j].rgbtBlue = (copy[i][j].rgbtBlue + copy[i - 1][j - 1].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i][j + 1].rgbtBlue) / 6;
}
//all else
else {
image[i][j].rgbtRed = (copy[i - 1][j - 1].rgbtRed + copy[i - 1][j].rgbtRed + copy[i - 1][j + 1].rgbtRed + copy[i][j - 1].rgbtRed + copy[i][j].rgbtRed + copy[i][j + 1].rgbtRed + copy[i + 1][j - 1].rgbtRed + copy[i + 1][j].rgbtRed + copy[i + 1][j + 1].rgbtRed) / 9;
image[i][j].rgbtGreen = (copy[i - 1][j - 1].rgbtGreen + copy[i - 1][j].rgbtGreen + copy[i - 1][j + 1].rgbtGreen + copy[i][j - 1].rgbtGreen + copy[i][j].rgbtGreen + copy[i][j + 1].rgbtGreen + copy[i + 1][j - 1].rgbtGreen + copy[i + 1][j].rgbtGreen + copy[i + 1][j + 1].rgbtGreen) / 9;
image[i][j].rgbtBlue = (copy[i - 1][j - 1].rgbtBlue + copy[i - 1][j].rgbtBlue + copy[i - 1][j + 1].rgbtBlue + copy[i][j - 1].rgbtBlue + copy[i][j].rgbtBlue + copy[i][j + 1].rgbtBlue + copy[i + 1][j - 1].rgbtBlue + copy[i + 1][j].rgbtBlue + copy[i + 1][j + 1].rgbtBlue) / 9;
}
}
}
return;
}
/**
My code correctly works on all the stock images, for all the functions (grayscale, sepia, reverse, and blur),
however, the check50 is only giving me 7 out of 22 correct. I'm sure I built my code in a roundabout way,
but I'm not sure why it's failing these checks since it achieves the desired function.
These are the errors I receive when I run the code through the CS50 Check:
:) helpers.c exists
:) filter compiles
:) grayscale correctly filters single pixel with whole number average
:( grayscale correctly filters single pixel without whole number average
expected "28 28 28\n", not "27 27 27\n"
:) grayscale leaves alone pixels that are already gray
:) grayscale correctly filters simple 3x3 image
:( grayscale correctly filters more complex 3x3 image
expected "20 20 20\n50 5...", not "20 20 20\n50 5..."
:( grayscale correctly filters 4x4 image
expected "20 20 20\n50 5...", not "20 20 20\n50 5..."
:( sepia correctly filters single pixel
expected "56 50 39\n", not "55 49 38\n"
:( sepia correctly filters simple 3x3 image
expected "100 89 69\n100...", not "100 88 69\n100..."
:( sepia correctly filters more complex 3x3 image
expected "25 22 17\n66 5...", not "24 22 17\n65 5..."
:( sepia correctly filters 4x4 image
expected "25 22 17\n66 5...", not "24 22 17\n65 5..."
:( reflect correctly filters 1x2 image
expected "0 0 255\n255 0...", not "3 0 0\n0 0 255..."
:( reflect correctly filters 1x3 image
expected "0 0 255\n0 255...", not "207 25 225\n0 ..."
:( reflect correctly filters image that is its own mirror image
expected "255 0 0\n255 0...", not "0 255 0\n255 0..."
:( reflect correctly filters 3x3 image
expected "70 80 90\n40 5...", not "110 130 140\n4..."
:( reflect correctly filters 4x4 image
expected "100 110 120\n7...", not "110 130 140\n1..."
:( blur correctly filters middle pixel
expected "127 140 149\n", not "126 140 149\n"
:) blur correctly filters pixel on edge
:) blur correctly filters pixel in corner
:( blur correctly filters 3x3 image
expected "70 85 95\n80 9...", not "70 85 95\n80 9..."
:( blur correctly filters 4x4 image
expected "70 85 95\n80 9...", not "70 85 95\n80 9..."
*/
@JmontB
Copy link

JmontB commented Jun 12, 2020

Yo, just an opinion, it'd be better coded if you use a CAP function, it's the same code you got for the SEPIA filter but you can save some lines of code there!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment