-
-
Save voidnerd/85e910bc6299022de95365948ef8f485 to your computer and use it in GitHub Desktop.
#include "helpers.h" | |
#include <math.h> | |
// Convert image to grayscale | |
void grayscale(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
float rgbGray; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) { | |
rgbGray = round( (image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed)/ 3.00); | |
image[i][j].rgbtBlue = rgbGray; | |
image[i][j].rgbtGreen = rgbGray; | |
image[i][j].rgbtRed = rgbGray; | |
} | |
} | |
return; | |
} | |
int limit(int RGB) | |
{ | |
if (RGB > 255) | |
{ | |
RGB = 255; | |
} | |
return RGB; | |
} | |
// Convert image to sepia | |
void sepia(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
int sepiaBlue; | |
int sepiaRed; | |
int sepiaGreen; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
sepiaBlue = limit(round(0.272 * image[i][j].rgbtRed + 0.534 * image[i][j].rgbtGreen + 0.131 * image[i][j].rgbtBlue)); | |
sepiaGreen = limit(round(0.349 * image[i][j].rgbtRed + 0.686 * image[i][j].rgbtGreen + 0.168 * image[i][j].rgbtBlue)); | |
sepiaRed = limit(round(0.393 * image[i][j].rgbtRed + 0.769 * image[i][j].rgbtGreen + 0.189 * image[i][j].rgbtBlue)); | |
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]) | |
{ | |
int temp[3]; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width / 2; j++) { | |
/** Swap pixels from left to right */ | |
temp[0] = image[i][j].rgbtBlue; | |
temp[1] = image[i][j].rgbtGreen; | |
temp[2] = image[i][j].rgbtRed; | |
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue; | |
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen; | |
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed; | |
image[i][width - j - 1].rgbtBlue = temp[0]; | |
image[i][width - j - 1].rgbtGreen = temp[1]; | |
image[i][width - j - 1].rgbtRed = temp[2]; | |
} | |
} | |
return; | |
} | |
int getBlur(int i, int j, int height, int width, RGBTRIPLE image[height][width] , int color_position) | |
{ | |
float counter = 0; | |
int sum = 0; | |
/** Start from 1 row before it and end at 1 row after it- total of 3rows */ | |
for (int k = i - 1; k < (i + 2); k++) | |
{ | |
/** Start from 1 block before it and end at 1 block after it- total of 3blocks */ | |
for (int l = j - 1; l < (j + 2); l ++) | |
{ | |
if(k < 0 || l < 0 || k >= height || l >= width) | |
{ | |
continue; | |
} | |
if (color_position == 0) | |
{ | |
sum += image[k][l].rgbtRed; | |
} | |
else if (color_position == 1) | |
{ | |
sum += image[k][l].rgbtGreen; | |
} | |
else | |
{ | |
sum += image[k][l].rgbtBlue; | |
} | |
counter++; | |
} | |
} | |
return round(sum /counter); | |
} | |
// Blur image | |
void blur(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
RGBTRIPLE copy[height][width]; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
copy[i][j] = image[i][j]; | |
} | |
} | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
image[i][j].rgbtRed = getBlur(i, j, height, width, copy, 0); | |
image[i][j].rgbtGreen = getBlur(i, j, height, width, copy, 1); | |
image[i][j].rgbtBlue = getBlur(i, j, height, width, copy, 2); | |
} | |
} | |
return; | |
} |
Hey, thanks for this great code. I had multiple instances of going "Holy shit, that's so clever!".
Hope I'll be able to figure out such things on my own soon enough :D
in the blur function, why do we have to make a copy of image? Can't we use image[i][j] right away?
i really couldnt understand line 67 , why did we put it this way {image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue} why did we put that -1 ?
I know this was like an year ago but , as you may recall in the lectures, it was mentioned that in a loop starting at 0. the last column will be width - 1. so to access the last column, we put a -1
in the blur function, why do we have to make a copy of image? Can't we use image[i][j] right away?
You need a copy of the image because you will be modifying the pixels of the original one in each loop. If you don't work with a copy you would be calculating the average of blue (for example) with pixels that are already the average of the surrounding pixels
You can make the reflect even more compact by using the defined RGBTruple. Since we dont alter the RGB I tried to find a way just to save the pixel value, thought it was bool first but checked the bmp.h
`
RGBTRIPLE tValue = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = tValue;
`
@Saifbabrak I'll try, so my understanding is the pixel maps of these images for width and height start at 0 because it is an array. so position 0 is the first pixel. say we have an image that is 4 pixels wide, 4 pixels is our width, but the first pixel is going to be in position 0. so when J = 0 it is referring to the pixel in the leftmost position. that means the rightmost pixel in the 4 pixel wide image is in position 3. so if we just did [width - j], and j was 0 (the leftmost pixel), then our [width - j] will give us a value of [4], and since the pixel map for goes from left to right as [0] [1] [2] [3], then 4 is out of the array range.
can someone please tell me if I'm right? i am taking cs50 right now as a highschool senior but I am the biggest brick anyone has ever seen.