Skip to main content

How To Think Like a Computer Scientist C++ Edition The Pretext Interactive Version

Exercises 12.14 Coding Practice

1.

A pixel is the smallest controllable element of a picture represented on the screen. Images are comprised of numerous individual pixels, and each pixel’s color sample has three numerical RGB (red, green, blue) components to represent the color of that pixel. The intensity value of each RGB component ranges from 0 to 255, where 0 is no intensity and 255 is highest intensity. Write the struct definition for Pixel, which has values for each component r, g, and b.
Solution.
Below is one way to implement the program. We declare the Pixel struct and create the instance variables in order.
#include <iostream>
#include <vector>
using namespace std;

struct Pixel {
    int r;
    int g;
    int b;
};

2.

An image is just a matrix of pixels. Write the struct definition for Image, which should store information about its height and width and contain a matrix of Pixels. Check the hint below for help with the construction of the code.
Hint.

Activity 12.14.1.

An image is just a matrix of pixels. Write the struct definition for Image, which should store information about its height and width and contain a matrix of Pixels. Use the lines to construct the code, then go back to complete the Activecode.

3.

Let’s print out a Pixel! Write the Pixel member function printPixel, which prints out the values of the Pixel in this form: (r, g, b).
Solution.
Below is one way to implement the program. We use the scope resolution operator to make printPixel a Pixel member function.
#include <iostream>
#include <vector>
using namespace std;

struct Pixel {
    int r;
    int g;
    int b;
    void printPixel();
};

void Pixel::printPixel() {
    cout << "("<< r << ", " << g << ", " << b << ")";
}

int main() {
    Pixel p = {0, 0, 0};
    p.printPixel();
}

4.

Now let’s print an Image. Unfortunately we can’t print out the actual image to the terminal, but we can print out the Pixels in the Image matrix. Write the Image member function printImage. Separate pixels in the same row with a space and add a new line at the end of each row. Use the printPixel function we created previously. Check the hint below for help with the construction of the code.
Hint.

Activity 12.14.2.

Now let’s print an Image. Unfortunately we can’t print out the actual image to the terminal, but we can print out the Pixels in the Image matrix. Write the Image member function printImage. Separate pixels in the same row with a space and add a new line at the end of each row. Use the printPixel function we created previously. Use the lines to construct the code, then go back to complete the Activecode.

5.

Somebody photobombed our image! What if we wanted to crop the photobomber out? Let’s write the Image member function cropImage, which takes four paramenters, a start and stop row and a start and stop column. It then modifies the matrix to the cropped matrix.
Solution.
Below is one way to implement the program. First we make a new matrix with the correct amount of rows. Then we push back the pixels we want into the new matrix. Afterwards, we must update the height and width of the Image and set the Image’s matrix equal to the new one we created.
#include <iostream>
#include <vector>
using namespace std;

struct Pixel {
    int r;
    int g;
    int b;
    void printPixel();
};

struct Image {
    int height;
    int width;
    vector<vector<Pixel> > matrix;
    void printImage();
    void cropImage(int startRow, int stopRow, int startCol, int stopCol);
};

void Image::cropImage(int startRow, int stopRow, int startCol, int stopCol) {
    vector<vector<Pixel> > newMatrix(stopRow - startRow + 1);
    for (int r = startRow - 1; r < stopRow; ++r) {
        for (int c = startCol - 1; c < stopCol; ++c) {
            newMatrix[r - (startRow - 1)].push_back(matrix[r][c]);
        }
    }
    height = stopRow - startRow + 1;
    width = stopCol - startCol + 1;
    matrix = newMatrix;
}

int main() {
    vector<vector<Pixel> > matrix = { { { 0, 255, 255 }, { 0, 0, 0 }, { 255, 255, 255 } },
                                      { { 30, 60, 50 }, { 20, 135, 200 }, { 60, 80, 125 } },
                                      { { 10, 0, 50 }, { 30, 65, 225 }, { 25, 105, 125 } },
                                      { { 255, 60, 0 }, { 20, 25, 255 }, { 65, 55, 0 } } };
    Image image = { 4, 3, matrix };
    image.printImage();
    cout << endl;
    image.cropImage(2, 3, 1, 2);
    image.printImage();
}

6.

Let’s write a swapPixel member function for Image. swapPixel takes two pairs of row indices and column indices from a matrix and swaps the two Pixels at those locations. Note that these indices are 0-indexed, unlike the previous cropIndex parameters. Check the hint below for help with the construction of the code.
Hint.

Activity 12.14.3.

Let’s write a swapPixel member function for Image. swapPixel takes two pairs of row indices and column indices from a matrix and swaps the two Pixels at those locations. Note that these indices are 0-indexed, unlike the previous cropIndex parameters. Use the lines to construct the code, then go back to complete the Activecode.

7.

When you take a selfie on your phone, the image is mirrored. We can do the same to an image by flipping it horizontally. Write the Image member function flipHorizontal, which flips an image horizontally. Use the swapPixel function we created previously.
Solution.
Below is one way to implement the program. We loop through each row in the matrix. We create start and end indices and repeatedly swap pixels, moving both indices toward the middle. Once they meet in the middle, we have finished flipping the image.
#include <iostream>
#include <vector>
using namespace std;

struct Pixel {
    int r;
    int g;
    int b;
    void printPixel();
};

struct Image {
    int height;
    int width;
    vector<vector<Pixel> > matrix;
    void printImage();
    void cropImage(int startRow, int stopRow, int startCol, int stopCol);
    void swapPixel(int row1, int col1, int row2, int col2);
    void flipHorizontal();
};

void Image::flipHorizontal() {
    for (int r = 0; r < height; ++r) {
        int start = 0;
        int end = width - 1;
        while (start < end) {
            swapPixel(r, start, r, end);
            ++start;
            --end;
        }
    }
}

int main() {
    vector<vector<Pixel> > matrix = { { { 0, 0, 0 }, { 10, 10, 10 }, { 255, 255, 255 } },
                                      { { 50, 50, 50 }, { 10, 10, 10 }, { 255, 255, 255 } },
                                      { { 100, 100, 100 }, { 10, 10, 10 }, { 255, 255, 255 } },
                                      { { 150, 150, 150 }, { 10, 10, 10 }, { 255, 255, 255 } } };
    Image image = { 4, 3, matrix };
    image.printImage();
    cout << endl;
    image.flipHorizontal();
    image.printImage();
}

8.

Oops! Somehow our image came out upside down. Let’s write the Image member function flipVertical, which reverts an image to be right side up. Check the hint below for help with the construction of the code.
Hint.

Activity 12.14.4.

Oops! Somehow our image came out upside down. Let’s write the Image member function flipVertical, which reverts an image to be right side up. Use the lines to construct the code, then go back to complete the Activecode.

9.

Let’s write the Image member function called createBorder, which sets the Pixels on the edge of an Image to a given Pixel.
Solution.
Below is one way to implement the program. We set the first and last row and first and last column of Pixels in the Image to the given Pixel.
#include <iostream>
#include <vector>
using namespace std;

struct Pixel {
    int r;
    int g;
    int b;
    void printPixel();
};

struct Image {
    int height;
    int width;
    vector<vector<Pixel> > matrix;
    void printImage();
    void cropImage(int startRow, int stopRow, int startCol, int stopCol);
    void swapPixel(int row1, int col1, int row2, int col2);
    void flipHorizontal();
    void flipVertical();
    void createBorder(Pixel p);
};

void Image::createBorder(Pixel p) {
    for (int r = 0; r < height; ++r) {
        matrix[r][0] = p;
        matrix[r][width - 1] = p;
    }
    for (int c = 0; c < width; ++c) {
        matrix[0][c] = p;
        matrix[height - 1][c] = p;
    }
}

int main() {
    vector<vector<Pixel> > matrix = { { { 25, 65, 23 }, { 73, 56, 24 }, { 255, 255, 255 }, { 253, 61, 56 } },
                                      { { 50, 50, 50 }, { 145, 52, 102 }, { 2, 0, 25 }, { 52, 47, 35 } },
                                      { { 45, 34, 100 }, { 213, 67, 45 }, { 2, 45, 255 }, { 34, 16, 76 } },
                                      { { 2, 2, 78 }, { 164, 16, 23 }, { 5, 255, 25 }, { 32, 65, 34 } },
                                      { { 150, 150, 150 }, { 241, 42, 64 }, { 1, 4, 255 }, { 16, 73, 84 } } };
    Image image = { 5, 4, matrix };
    image.printImage();
    cout << endl;
    Pixel p = { 0, 0, 0 };
    image.createBorder(p);
    image.printImage();
}

10.

Let’s return our image to the state of a clean slate. Write the function clearImage, which sets the color of every Pixel to white. Check the hint below for help with the construction of the code.
Hint.

Activity 12.14.5.

Let’s return our image to the state of a clean slate. Write the function clearImage, which sets the color of every Pixel to white. Use the lines to construct the code, then go back to complete the Activecode.
You have attempted 1 of 16 activities on this page.