GrayImage 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 1 respectively and the matrix of values is called pixelValues. We’ll need to know that for the two parts.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *