Starting to do some really fun stuff and get into image and data manipulation! Here we practice handling pixels in BMP files and altering their values. There is also a practice project where we alter the bits in a WAV file and change the volume of a sound file!
N A V I G A T I O N
Smiley
Yay! Image practice work! Let's get to it!
Our goal: There's a BMP file of a smiley face. We need to take the black pixels and convert them to a color of our choice!
Good news is, we only need to manipulate single pixels at a time. (Not needing to take into account anything else).
All of the base code is already written by the CS50 team. There is only one function inside a separate C file called helpers.c. There is a function inside of this class called colorize. It takes into account the image height, width, and image RGB values. Since CS50's program calls colorize after reading the BMP into memory and before writing it out to the new file, this is our opportunity to manipulate. Since image scanlines are nothing more than a row of pixels we can go through each row of pixels pixel-by-pixel. So, we will call a nested for loop (the most general way to scan through columns by row) and check each pixel value for black pixels RGBTRIPLE 0, 0, 0. After doing this we can just change those particular pixels to whatever color our hearts desire. In my case, a crazy purple color RGB(128, 0, 255). Since all of this code was custom (except for the function call), I will just dump it below so you can see it all at once.
#include "helpers.h"
void colorize(int height, int width, RGBTRIPLE image[height][width]) { // Change all black pixels to a color of your choosing for (int r = 0; r < height; r++) { for (int c = 0; c < width; c++) { if ((image[r][c].rgbtBlue == 0) && (image[r][c].rgbtGreen == 0) && (image[r][c].rgbtRed == 0)) { image[r][c].rgbtBlue = 255; image[r][c].rgbtGreen = 0; image[r][c].rgbtRed = 128; } } } } This code scans through each pixel by row (r) and column (p) and looks for black (RGB(0,0,0)) and replaces it with my new pixel color (RGB(128,0,255)). Bring on the next lab!
Read from a WAV file. Write to a WAV file. Oh, yeah, increase the volume of the WAV based on the user's input!
Okay, this is not as terrible as it sounds. (Get it? Sounds?)
CS50 takes care of our file load and prep. Our jobs is to read/write the header and manipulate the bits so that the volume is changed accordingly. This required reading/writing the 8bit header to/from the input/output files. (Pretty straight forward.) Then, looping through all of the remaining bits - 2 bytes at a time - and amplifying them by the factor provided by the user. This took a bit more work with an int16_t type and multiplying each bit. Came out great, though! Each test resulted in a WAV with a different volume and it passed the check50 test and Valgrind!
// Modifies the volume of an audio file
#include <stdint.h> #include <stdio.h> #include <stdlib.h> // Number of bytes in .wav header const int HEADER_SIZE = 44; int main(int argc, char *argv[]) { // Check command-line arguments if (argc != 4) { printf("Usage: ./volume input.wav output.wav factor\n"); return 1; } // Open files and determine scaling factor FILE *input = fopen(argv[1], "r"); if (input == NULL) { printf("Could not open file.\n"); return 1; } FILE *output = fopen(argv[2], "w"); if (output == NULL) { printf("Could not open file.\n"); return 1; } float factor = atof(argv[3]); // TODO: Copy header from input file to output file uint8_t *header[HEADER_SIZE]; fread(header, HEADER_SIZE, 1, input); fwrite(header, HEADER_SIZE, 1, output); // TODO: Read samples from input file and write updated data to output file int16_t *sample = malloc(sizeof(sample) + 1); while (fread(sample, 2, 1, input) != 0) { for (int s = 0; s < 2; s++) { sample[s] = sample[s] * factor; } fwrite(sample, 2, 1, output); } // Close files free(sample); fclose(input); fclose(output); }
0 Comments
Leave a Reply. |
Weeks navWeek 0AuthorJonathan Styles (4verageGamer) is just a simple student of all things IT-related during this pursuit of completing the CS50 class from Harvard. Archives |