DEV Community

Cover image for CS50 week-4 Images + PSet: Filter(more)

Posted on • Updated on

CS50 week-4 Images + PSet: Filter(more)

This post aims to review the knowledge we learned this week regarding pixels (images) and apply it to understand and solve the 'Filter' problem in CS50 Week 4, which is a more difficult version.


Pixels are the basic building blocks of digital visuals and are arranged in a grid to form images, videos, text, or any visible thing on a computer screen.

Image description
As we see in the picture above. The small squares or pixels are the building blocks of an image.
Each pixel has 3 bytes of information for Red, Blue, and Green ranging from 0x00 to 0xFF (255) i.e. 11111111 (8 bits in Binary).
So a total of 24 bits represents a pixel’s color.

Image description

  • 0xffffff signifies White
  • 0x000000 signifies Black
  • Now what does 0x prefix mean?
  • This turns out to be another base system known as Hexadecimal
  • This system follows base 16 and they are:
0 1 2 3 4 5 6 7 8 9 A B C D E F

Now before moving forward, we will have a quick recap of Files.

File I/O

Now take a look at the code below; this code is to open a CSV file, which is somewhat similar to Excel and uses commas to separate values and newlines to separate records.

    // Open CSV file
    FILE *file = fopen("phonebook.csv", "a"); //fopen gives us file pointer
    if (!file)                                //"a" - append;"w"-write;"r"-read
        return 1;

    // Get name and number
    char *name = get_string("Name: ");
    char *number = get_string("Number: ");

    // Print to file ~ to write
    fprintf(file, "%s,%s\n", name, number);

    // Close file

Enter fullscreen mode Exit fullscreen mode
  • Notice that this code uses pointers to access the file.
  • You can create a file called phonebook.csv in advance of running the above code. After running the above program and inputting a name and phone number, you will notice that this data persists in your CSV file.
  • Notice that this program protects against a NULL pointer by invoking return 1.

Other important functions:


fread(&b, sizeof(b), 1, src):

  • &b → is the buffer variable (to where we read into)
  • src → pointer(from where we read from)
  • sizeof(b) → how big the building piece of data is (img → pixel;text →char)
  • 1→ How many of these chunks should be read at a time.It returns the number of blocks it read.


fwrite(&b, sizeof(b), 1, dst):

  • &b → is buffer variable (to where we write from)
  • dst → pointer(from where we write into)
  • sizeof(b) → how big the building piece of data is (img → pixel;text →char)
  • 1→ how many of these chunks should be read at a time.
  • EOF - end of file character

BMP(Bitmap Image file)

  • Every file type has its unique signature at the beginning which tells us the file type. eg: pdf has a 4-byte sequence i.e. 37;80;68;70.
  • A 24-bit BMP file, then, is essentially just a sequence of bits, (almost) every 24 of which happen to represent some pixel’s color. However, BMP stores these triples backwards (i.e., as BGR), with 8 bits for blue, followed by 8 bits for green, followed by 8 bits for red.
    Image description

  • BMP file also contains some metadata, information like an image’s height and width. That metadata is stored at the beginning of the file in the form of two data structures generally referred to as headers.

  • Now when we open the file provided to us as a distribution code.


  • This file stores the information about Bitmap images.It defines the Structure to create a bitmap image.


  • It is the first of the headers and is 14 bytes long, and it stores the information about the type, size, and layout of a file (structure as defined by the creator of BMP).


  • The second of these headers, and is 40 bytes long. It stores information about the dimensions and color format.

  • It is immediately followed by the actual bitmap.


  • This structure describes a color consisting of relative intensities of red, green, and blue.

typedef struct
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
Enter fullscreen mode Exit fullscreen mode


It just provides the function prototypes for the functions we have to write.

Here each function takes a 2D array called image as an argument, where the image is an array[height, width] i.e. (n,m). So if the image represents the whole picture, then image[0] represents the first row, and image[0][0] represents the pixel in the upper-left corner of the image.


This file specifies what should happen when we run a terminal command like : 

  • make filter
  • As filter.c seems to use multiple files like filter.c and helpers.c. So we’ll need to tell make how to compile this file.
  • Remember, we should compile filter.c, not helpers.c.

And the main chunk in our code :


Here’s where the implementation of the functions declared in helpers.h belong. This is the part that we actually have to code.


It is the main program that applies image filters to bitmap files. It uses functions defined in helper and bmp defined in BMP.h to apply the filters.

Join me in my next blog post for an in-depth explanation of helper.c and filter.c files. See you there! In the meantime continue to code with passion. 🚀

As this is my debut blog post, I’m eager to learn and improve. Should you spot any errors, I warmly welcome your insights in the comments below. Your feedback is invaluable to me.

My code:

GitHub logo vivekvohra / filter

This code requires <cs50 library> to run.


In this problem, we have to code the following filter:

  • Grayscale function takes an image and turns it into a black-and-white version of the same image.

  • Reflect function takes an image and reflects it horizontally.

  • Blur function takes an image and turns it into a box-blurred version of the same image.

  • Edge function takes an image and highlights the edges between objects, according to the Sobel operator.


This function takes an image and converts it into a black-and-white version of the same image. This is done by taking an average of the RGB values of each pixel and setting them all equal to the average.


This function flips an image about the vertical axis, which returns a mirror image.


The purpose here is to return a blurred version of the input image. We do this by implementing the “box blur,” which works by taking each pixel…

Top comments (0)