Gray Image Free Response Solution

The GrayImage free response problem from the 2012 AP Computer Science exam has you working with a 2 dimensional array of integer values.

The class you’re given looks something like this, except with a lot more comments.

public class GrayImage {
  public static final int BLACK = 0;
  public static final int WHITE = 255;
  private int[][] pixelValues;
  public int countWhitePixels() {
    // Part A
  }
  public void processImage() {
    // Part B
  }
}

The two things to notice are that we have constants named BLACK and WHITE which are 0 and 255 respectively and the matrix of values is called pixelValues. We’ll need to know that for the two parts.

In the examples below I’m going to use the constant values BLACK and WHITE to represent black and white, but you could have used 0 and 255 instead.

Part A

The countWhitePixels method goes through pixelValues and counts how many cells are equal to WHITE or 255.

Let’s solve it first with a for loop.

public int countWhitePixels() {
  int cnt = 0;
  for (int r=0; r<pixelValues.length; r++) {
    for (int c=0; c<pixelValues[r].length; c++) {
      if (pixelValues[r][c] == WHITE)
        cnt++; 
    }
  }
  return cnt; 
}

It’s a nested loop checking every cell and incrementing cnt if the cell is equal to WHITE.

Here’s the same method, this time solved with a for each loop.

public int countWhitePixels() {
  int cnt = 0;
  for (int[] row: pixelValues) {
    for (int val: row) {
      if (val == WHITE)
        cnt++;
    }
  }
  return cnt; 
}

You could also solve it with a while loop, but I’m going to leave that one off.

Part B

For the second part, processImage, you’re going through the matrix and subtracting the value 2 rows down and 2 columns to the right from each cell, but only if there is a cell 2 down and 2 to the right. My guess is that this part of the test is checking that you know how loops work to keep your code in bounds.

public void processImage() {
  for (int r=0; r<pixelValues.length-2; r++) {
    for (int c=0; c<pixelValues[r].length-2; c++) {
      pixelValues[r][c] -= pixelValues[r+2][c+2];
      if (pixelValues[r][c] < BLACK)
        pixelValues[r][c] = BLACK;
    }
  }
}

I stopped my loops at < pixelValues.length-2 and < pixelValues[r].length-2 so that pixelValues[r+2][c+2] was always in bounds. The other option would be to loop through the entire thing and then check that pixelValues[r+2][c+2] was in bounds before subtracting it from pixelValues[r][c]. To me though, that just seems like another place to mess up.

After the value is subtracted my code checks that it’s not < BLACK, and if it is set it to BLACK.

This site contains affiliate links. If you click an affiliate link and make a purchase we may get a small commission. It doesn't affect the price you pay, but it is something we must disclose.