### Using 2-dimensional arrays --- manipulating pictures

• Pictures and 2-dimensional arrays

• A 2-dimensional arry is a natural representation of a picture

• Picture:

\$64,000 question:

 How do you represent a picture ???

• Picture encoding scheme:

• We first design a coordinate system for the picture:

Note:

 This coordinate system is the same one used for the Canvas program (see: click here) --- the Canvas program was designed by people who developed the Java language)

• The picture consists of many number of (rows of) dots:

A dot is called a pixel.

Each pixel has a color...

(Now, how do we represent a color ???)

• The color of a pixel can be represented by an integer value

A color can be represented as 3 primary colors (for light, the primary colors are red, green and blue (RGB)).

Color encoding scheme:

 ``` color = red_level × 2562 + green_level × 256 + blue_level red_level range = 0 .. 255 green_level range = 0 .. 255 blue_level range = 0 .. 255 ```

Some examples of color codes:

 ``` Color code Actual color --------------------------------------- 0 black 255 blue 65280 (255*256) green 16711680 (255*2562 red 16777215 white ```

The color white is a combination of all 3 primary colors:

 ``` 16777215 = 16711680 + 65280 + 255 (code for white) (red) (green) (blue) ```

• Conclusion:

 We can store (represent) a picture using a 2-dimensional array of int.

• Example: encoding a picture

• Sample picture:

The picture (inside the frame) Encoding (representation) of the picture

Simplified encoding:

0 = black   and   1 = yellow

```  2-dimensional array:

0   1   2   3
+---+---+---+---+---+ ...
0 | 0 | 0 | 0 | 0 | 0 | ...
+---+---+---+---+---+...
1 | 0 | 0 | 0 | 0 | 0 | ...
+---+---+---+---+---+ ...
..  ..  ..  ..  ..   ...
+---+---+---+---+---+ ...
23 | 0 | 0 | 0 | 1 | 0 | ...
+---+---+---+---+---+ ...
24 | 0 | 0 | 0 | 1 | 0 | ...
+---+---+---+---+---+ ...
25 | 0 | 0 | 1 | 1 | 1 | ...
+---+---+---+---+---+ ...
..  ..  ..  ..  ..   ...
```

(In reality, the value 1 should be 0xFFFF00 (Hex) (see: click here) or 16776960 (decimal))

• How to represent the picture:

• First, we must define a suitable type of variable to store the information.

From the above discussion, it is a 2-dimensional array of int:

 ``` int[][] a = new int[400][300]; // 400 columns x 300 rows ```

How is this variable used:

 a[0][0] is an int variable and will contain the color code for the pixel at coordinate (0,0) (Recall the coordinate system is: (column-index, row-index)). a[0][1] is an int variable and will contain the color code for the pixel at coordinate (0,1) a[0][2] is an int variable and will contain the color code for the pixel at coordinate (0,2) And so on !!!

In general:

 a[col][row] is an int variable and will contain the color code for the pixel at coordinate (col,row).

• Next, we store the color code of each pixel of the picture into the array a:

 ``` a[0][0] = 0; // 0 = code for black a[0][1] = 0; .... // Only these pixels have the color YELLOW // A vertical yellow line (col coord unchanged) a[100][191] = YELLOW; a[100][192] = YELLOW; a[100][193] = YELLOW; a[100][194] = YELLOW; a[100][195] = YELLOW; a[100][196] = YELLOW; a[100][197] = YELLOW; a[100][198] = YELLOW; a[100][199] = YELLOW; a[100][200] = YELLOW; a[100][201] = YELLOW; a[100][202] = YELLOW; a[100][203] = YELLOW; a[100][204] = YELLOW; a[100][205] = YELLOW; a[100][206] = YELLOW; a[100][207] = YELLOW; a[100][208] = YELLOW; a[100][209] = YELLOW; a[100][210] = YELLOW; a[100][211] = YELLOW; // A horizontal yellow line (row coord unchanged) a[96][201] = YELLOW; a[95][201] = YELLOW; a[94][201] = YELLOW; a[99][201] = YELLOW; a[98][201] = YELLOW; a[97][201] = YELLOW; a[101][201] = YELLOW; a[102][201] = YELLOW; a[103][201] = YELLOW; a[104][201] = YELLOW; a[105][201] = YELLOW; a[106][201] = YELLOW; ```

• Making a picture stored in a 2-dimensional array visible on screen

• Recall:

 We did not have enough background to understand how graphics works in Java So.... I will provide a class with a method that you can use to display the image (picture) stored in a 2-dimensional array But.... I need to tell you how to use the method

• Drawing a picture that is stored in a 2-dimenional array:

 ``` static public void main(String[] args) throws Exception { /* ------------------------------------------------ Preparing to draw picture... ------------------------------------------------ */ MyCanvas pic = new MyCanvas(); // Make a canvas (2 dim array) Frame f = new Frame( "My image" ); // Create a window f.add("Center", pic); // Put the canvas in the window f.setSize(400,300); // We make a 400x300 picture f.setVisible(true); // Make window visible /* ---------------------------------------------------- Draw a picture stored in a 2-dimensional array ---------------------------------------------------- */ int[][] a = new int[400][300]; // This array hold the picture // You will need write statements here to store the // correct pixel codes into the variable a first.... pic.draw(a); // This method call will display the picture // stored in the variable a to the screen } ```

• Example: (draw the picture above)

 ``` import java.awt.*; import java.awt.image.*; public class Draw1 { static public void main(String[] args) throws Exception { final int YELLOW = 0xFFFF00; final int BLACK = 0x000000; /* ------------------------------------------------ Preparing to draw picture... ------------------------------------------------ */ MyCanvas pic = new MyCanvas(); // Make a canvas (2 dim array) Frame f = new Frame( "My image" ); // Create a window f.add("Center", pic); // Put the canvas in the window f.setSize(400,300); // Set size of the window f.setVisible(true); // Make window visible int[][] a = new int[400][300]; // This array hold the picture int row, col; /* ------------------------------- Make the whole picture BLACK ------------------------------- */ for (col = 0; col < 400; col++ ) for (row = 0; row < 300; row++ ) a[col][row] = BLACK; /* -------------------------------------------------- Make a vertical yellow line (col coord unchanged) -------------------------------------------------- */ a[100][191] = YELLOW; a[100][192] = YELLOW; a[100][193] = YELLOW; a[100][194] = YELLOW; a[100][195] = YELLOW; a[100][196] = YELLOW; a[100][197] = YELLOW; a[100][198] = YELLOW; a[100][199] = YELLOW; a[100][200] = YELLOW; a[100][201] = YELLOW; a[100][202] = YELLOW; a[100][203] = YELLOW; a[100][204] = YELLOW; a[100][205] = YELLOW; a[100][206] = YELLOW; a[100][207] = YELLOW; a[100][208] = YELLOW; a[100][209] = YELLOW; a[100][210] = YELLOW; a[100][211] = YELLOW; /* ----------------------------------------------------- Make a horizontal yellow line (row coord unchanged) ----------------------------------------------------- */ a[96][201] = YELLOW; a[95][201] = YELLOW; a[94][201] = YELLOW; a[99][201] = YELLOW; a[98][201] = YELLOW; a[97][201] = YELLOW; a[101][201] = YELLOW; a[102][201] = YELLOW; a[103][201] = YELLOW; a[104][201] = YELLOW; a[105][201] = YELLOW; a[106][201] = YELLOW; pic.draw(a); // Draw the picture in a[][] } } ```

• Example Program: (Demo above code)

• Make a picture move to the left

• Making the picture move to the left

Original picture Picture after moving to left

What really happens:

 The color of each pixel (dot) changes in such a way that gives the appearance that the picture has moved to the left !

• To make the picture move to the left, we must:

 replace each pixel (code) with the pixel (code) at the right

Explained with an illustration:

 ``` Pixel value at (col, row): a[col][row] Pixel value to the right of (col,row): a[col+1][row] Statement to replace pixel value at (col, row) with pixel value to its right: a[col][row] = a[col+1][row]; ```

What really happens with the representation of the picture is:

Value of the array representation before moving left Value of the array representation after moving left
``` Array a:

0    1    2    3
+----+----+----+----+ ...
0 | 56 | 78 | 12 | 34 | ...
+----+----+----+----+ ...
1 | 11 | 64 | 98 | 21 | ...
+----+----+----+----+ ...
2 | 29 | 13 | 75 | 43 | ...
+----+----+----+----+ ...
..   ..   ..   ..   ...
```
``` Array a:

0    1    2    3
+----+----+----+----+ ...
0 | 78 | 12 | 34 | 23 | ...
+----+----+----+----+ ...
1 | 64 | 98 | 21 | 87 | ...
+----+----+----+----+ ...
2 | 13 | 75 | 43 | 99 | ...
+----+----+----+----+ ...
..   ..   ..   ..   ...
```

• There is one little thing to take care off:

• What to do with the right-most column of pixels:

There are no pixels to the right for us to copy....

• Simple solution:

 Make the right most column into a column of black pixels

• Algorithm in pseudo code:

 ``` for column col = 0, 1, 2, ...., (lastColumn - 1) { fill column col with values in column (col+1); } fill column lastColumn with black pixel values; ```

• More refined algorithm in pseudo code:

 ``` for columns (col = 0, 1, 2, ...., (lastColumn - 1) ) { for rows ( row = 0, 1, ..., lastRow ) do a[col][row] = a[col+1][row]; } for rows ( row = 0, 1, ..., lastRow ) do a[lastColumn][row] = 0; // 0 = code for black ```

• Java Method:

• What information does the method need to do the task ?

 The method needs the pixel values in the 2-dimensional array: input parameter !!!

• What information does the method return ?

 The method does not produce any information; the values in the input array will be updated ---- return type is void

Java method:

 ``` /* =========================================================== The "move_left" method copies the "image" stored in the variable "pixel" one column to the left col col+1 . <-- . . <-- . . <-- . =========================================================== */ public static void move_left( int[][] pixel ) { int ncols, nrows; /* ------------------------------------------------ This nested for-loop copies all but one (the right most column) columns of the picture to the left (one column to the left) ------------------------------------------------ */ for ( int col = 0; col < 399; col++ ) for ( int row = 0; row < 300; row++ ) pixel[col][row] = pixel[col+1][row]; /* --------------------------------------------- Fill the right most column with BLACK pixels --------------------------------------------- */ for ( int row = 0; row < 300; row++ ) pixel[399][row] = 0; // Make column 399 into 0 = BLACK } ```

Note:

• The dimension of the picture is 400x300:

 ``` int[][] a = new int[400][300]; // width = 400, height = 300 ```

• Instead of using 399 to denote lastColumn−1, it is better to use:

 ``` a.length - 1 (because a.length = 400) ```

• Instead of using 300 to denote lastRow, it is better to use:

 ``` a[0].length (we usually use a[0]...) ```

• Example usage: we make a square move to the left continuously

 ``` static public void main(String[] args) throws Exception { final int YELLOW = 0xFFFF00; final int BLACK = 0x000000; /* ------------------------------------------------ Preparing to draw picture... ------------------------------------------------ */ MyCanvas pic = new MyCanvas(); // Make a canvas (2 dim array) Frame f = new Frame( "My image" ); // Create a window f.add("Center", pic); // Put the canvas in the window f.setSize(400,300); // Set size of the window f.setVisible(true); // Make window visible int[][] a = new int[400][300]; // This array hold the picture int row, col; /* ----------------------------------- Make every pixel into BLACK ----------------------------------- */ for (col = 0; col < 400; col++ ) for (row = 0; row < 300; row++ ) a[col][row] = BLACK; /* ----------------------------------- Make a YELLOW square (10x10) ----------------------------------- */ for (col = 100; col < 110; col++ ) for (row = 200; row < 210; row++ ) a[col][row] = YELLOW; /* ========================================== Move the picture to the left, 120 times ========================================== */ for ( int k = 0; k < 120; k++ ) { pic.draw(a); // Draw the picture in a[][] pause(1); // Pause 0.1 sec move_left(a); // Move the picture to left // Repeat these 3 steps for 120 times..... } System.exit(0); // Exit. } ```

• Example Program: (Demo above code)

How to run the program:

 Right click on links and save in a scratch directory To compile:   javac Draw3.java To run:          java Draw3

• Make a picture move to the right

• Making the picture move to the right

Original picture Picture after moving to right

• To make the picture move to the right, we must:

 replace each pixel (code) with the pixel (code) at the left

Explained with an illustration:

 ``` Pixel value at (col, row): a[col][row] Pixel value to the left of (col,row): a[col-1][row] Statement to replace pixel value at (col, row) with pixel value to its left: a[col][row] = a[col-1][row]; ```

What really happens with the representation of the picture is:

Value of the array representation before moving right Value of the array representation after moving right
``` Array a:

0    1    2    3
+----+----+----+----+ ...
0 | 56 | 78 | 12 | 34 | ...
+----+----+----+----+ ...
1 | 11 | 64 | 98 | 21 | ...
+----+----+----+----+ ...
2 | 29 | 13 | 75 | 43 | ...
+----+----+----+----+ ...
..   ..   ..   ..   ...
```
``` Array a:

0    1    2    3
+----+----+----+----+ ...
0 | 0  | 56 | 78 | 12 | ...
+----+----+----+----+ ...
1 | 0  | 11 | 64 | 98 | ...
+----+----+----+----+ ...
2 | 0  | 29 | 13 | 75 | ...
+----+----+----+----+ ...
..   ..   ..   ..   ...
```

• Note:

 When we move the picture to the right, the the left most column is filled with a column of black pixels

• Algorithm in pseudo code:

 ``` for column col = 1, 2, ...., (lastColumn) { fill column col with values in column (col-1); } fill column 0 with black pixel values; ```

• More refined algorithm in pseudo code:

 ``` for columns (col = 1, 2, ...., (lastColumn - 1) ) { for rows ( row = 0, 1, ..., lastRow ) do a[col][row] = a[col-1][row]; } for rows ( row = 0, 1, ..., lastRow ) do a[0][row] = 0; // 0 = code for black ```

• Java Method Input and Output:

• What information does the method need to do the task ?

 The method needs the pixel values in the 2-dimensional array: input parameter !!!

• What information does the method return ?

 The method does not produce any information; the values in the input array will be updated ---- return type is void

Java method ???? (this method does not work !)

 ``` /* =========================================================== The "move_right" method copies the "image" stored in the variable "pixel" one column to the right col-1 col . --> . . --> . . --> . =========================================================== */ public static void move_right( int[][] pixel ) { int ncols, nrows; /* ------------------------------------------------ This nested for-loop copies all but one (the right most column) columns of the picture to the right (one column to the right) ------------------------------------------------ */ for ( int col = 1; col < 400; col++ ) for ( int row = 0; row < 300; row++ ) pixel[col][row] = pixel[col-1][row]; /* --------------------------------------------- Fill the right most column with BLACK pixels --------------------------------------------- */ for ( int row = 0; row < 300; row++ ) pixel[0][row] = 0; // Make column 399 into 0 = BLACK } ```

Quiz:

 This method is not correct !!!! Can you find why it is wrong ????

Let's execute the algorithm for a small example

Initial values Iteration 1 - col=1: copy col 0 to col 1
``` Array pixel:

0    1    2    3
+----+----+----+----+
0 | 56 | 78 | 12 | 34 |
+----+----+----+----+
1 | 11 | 64 | 98 | 21 |
+----+----+----+----+
2 | 29 | 13 | 75 | 43 |
+----+----+----+----+
```
``` Array pixel:

0    1    2    3
+----+----+----+----+
0 | 56 | 56 | 12 | 34 |
+----+----+----+----+
1 | 11 | 11 | 98 | 21 |
+----+----+----+----+
2 | 29 | 29 | 75 | 43 |
+----+----+----+----+
```
Iteration 2 - col=2: copy col 1 to col 2 Iteration 3 - col=3: copy col 2 to col 3
``` Array pixel:

0    1    2    3
+----+----+----+----+
0 | 56 | 56 | 56 | 34 |
+----+----+----+----+
1 | 11 | 11 | 11 | 21 |
+----+----+----+----+
2 | 29 | 29 | 29 | 43 |
+----+----+----+----+
```
``` Array pixel:

0    1    2    3
+----+----+----+----+
0 | 56 | 56 | 56 | 56 |
+----+----+----+----+
1 | 11 | 11 | 11 | 11 |
+----+----+----+----+
2 | 29 | 29 | 29 | 29 |
+----+----+----+----+
```

Conclusion:

 We must copy the columns in reverse order, starting from the last column !!!

• Corrected java method:

 ``` /* =========================================================== The "move_right" method copies the "image" stored in the variable "pixel" one column to the right col-1 col . --> . . --> . . --> . =========================================================== */ public static void move_right( int[][] pixel ) { int ncols, nrows; /* ------------------------------------------------ This nested for-loop copies all but one (the right most column) columns of the picture to the right (one column to the right) ------------------------------------------------ */ for ( int col = 399; col > 0; col-- ) for ( int row = 0; row < 300; row++ ) pixel[col][row] = pixel[col-1][row]; /* --------------------------------------------- Fill the right most column with BLACK pixels --------------------------------------------- */ for ( int row = 0; row < 300; row++ ) pixel[0][row] = 0; // Make column 399 into 0 = BLACK } ```

Note:

• The dimension of the picture is 400x300:

 ``` int[][] a = new int[400][300]; // width = 400, height = 300 ```

• Instead of using 399 to denote lastColumn−1, it is better to use:

 ``` a.length - 1 (because a.length = 400) ```

• Instead of using 300 to denote lastRow, it is better to use:

 ``` a[0].length (we usually use a[0]...) ```

• Example usage: we make a square move to the right continuously

 ``` static public void main(String[] args) throws Exception { final int YELLOW = 0xFFFF00; final int BLACK = 0x000000; /* ------------------------------------------------ Preparing to draw picture... ------------------------------------------------ */ MyCanvas pic = new MyCanvas(); // Make a canvas (2 dim array) Frame f = new Frame( "My image" ); // Create a window f.add("Center", pic); // Put the canvas in the window f.setSize(400,300); // Set size of the window f.setVisible(true); // Make window visible int[][] a = new int[400][300]; // This array hold the picture int row, col; /* ----------------------------------- Make every pixel into BLACK ----------------------------------- */ for (col = 0; col < 400; col++ ) for (row = 0; row < 300; row++ ) a[col][row] = BLACK; /* ----------------------------------- Make a YELLOW square (10x10) ----------------------------------- */ for (col = 100; col < 110; col++ ) for (row = 200; row < 210; row++ ) a[col][row] = YELLOW; /* ========================================== Move the picture to the right, 120 times ========================================== */ for ( int k = 0; k < 120; k++ ) { pic.draw(a); // Draw the picture in a[][] pause(1); // Pause 0.1 sec move_right(a); // Move the picture to right // Repeat these 3 steps for 120 times..... } System.exit(0); // Exit. } ```

• Example Program: (Demo above code)

How to run the program:

 Right click on links and save in a scratch directory To compile:   javac Draw4.java To run:          java Draw4