Home
Time Box
Calculator
Snake
Blogs
Hacks

Unit 8 Lesson - 2D Arrays • 86 min read

Description

Group Lesson on Unit 8 which covers 2D arrays

  • Row Major Order Vs Column Major Order
  • Practice
  • Algorithms That use 2D Arrays Traversing
  • Hacks 8.2
  • Create your own situration of an Algorthm that needs to traverse a 2D array and then write the code for it
  • Image Representation with 2D Arrays
  • Scaling the Image
  • Images Hack
  • the png
  • the jpeg
  • Grading for Hacks

  • 8.1

    What is a 2D array

    A 2D array is an array of arrays.

    image.png

    Why use 2D arrays?

    1D array of people

    {
    "Patrick Mahomes"
    "Mr. Mortensen"
    "Taylor Swift"
    "Margot Robbie"
    }
    

    2D array of men and women

    {
    { "Patrick Mahomes", "Mr. Mortensen"} ,
    {"Taylor Swift", "Margot Robbie"}
    }
    

    Declaring a 2D Array

    Very similar to declaring a 1D array.

    DataType[] name // 1D array
    DataType[][] name // 2D array
    
    int[][] intArray; //primitive
    String[][] stringArray; //object
    

    Initalizing a 2D Array

    public class TwoDArrayExample {
        public static void main(String[] args) {
            int rows = 3;
            int cols = 4;
            
            // Declare and initialize a 2D array
            int[][] myArray = {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12}
            };
            
            // Access and print elements
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    System.out.print(myArray[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
    TwoDArrayExample.main(null)
    
    1 2 3 4 
    5 6 7 8 
    9 10 11 12 
    

    Popcorn HACK 1

    public class TwoDArrayHack1 {
        public static void main(String[] args) {
            int rows = 5;
            int columns = 4;
            // Declare and initialize a 2D array with 5 rows (arrays) and 4 columns (elements per array) of int data type.
            int[][] Array = {
      
    
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13,14, 15, 16},
                {17,18, 19, 20}
    
            };
            
        }
    
    }
    

    More Initializing and Accessing Array Elements of a 2D Array

    class Student {
        private String name;
        private int age;
    
        // Constructor to initialize a Student object
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        // Getter method to retrieve the student's name
        public String getName() {
            return name;
        }
    
        // Getter method to retrieve the student's age
        public int getAge() {
            return age;
        }
    
        // Method to print student information
        public void printInfo() {
            System.out.println("Name: " + name);
            System.out.println("Age: " + age);
        }
    }
    
    public class TwoDArrayHack2 {
        public static void main(String[] args) {
            // Declare and initialize a 2D array with 6 rows and 6 columns of Student objects
            Student[][] studentArray = new Student[6][6];
    
            // Creating and initializing Student objects in the array
            studentArray[0][0] = new Student("Yuri", 16);
            studentArray[1][2] = new Student("Gorlcok", 135);
    
            // Accessing and using the Student objects' methods
            String studentName = studentArray[0][0].getName();
            int studentAge = studentArray[0][0].getAge();
    
            System.out.println("Student Name: " + studentName);
            System.out.println("Student Age: " + studentAge);
    
            studentArray[1][2].printInfo();
        }
    }
    TwoDArrayHack2.main(null)
    
    Student Name: Yuri
    Student Age: 16
    Name: Gorlcok
    Age: 135
    

    More Initializing + Accessing + Popcorn HACK 2

    class NFLTeams {
        private String teamName;
        private String city;
        private int championships;
    
        // Constructor to initialize NFL team data
        public NFLTeams(String teamName, String city, int championships) {
            this.teamName = teamName;
            this.city = city;
            this.championships = championships;
        }
    
        // Method to display team information
        public void displayTeamInfo() {
            System.out.println("Team: " + teamName);
            System.out.println("City: " + city);
            System.out.println("Championships: " + championships);
        }
    }
    
    public class NFLTeams2DArray {
        public static void main(String[] args) {
            // Declare a 2D array of NFLTeams to store data for 5 teams and 5 columns
            NFLTeams[][] nflArray = {
                {new NFLTeams("Team1", "City1", 2), new NFLTeams("Team2", "City2", 3), new NFLTeams("Team3", "City3", 1), new NFLTeams("Team4", "City4", 0), new NFLTeams("Team5", "City5", 5)},
                {new NFLTeams("Team6", "City6", 3), new NFLTeams("Team7", "City7", 4), new NFLTeams("Team8", "City8", 0), new NFLTeams("Team9", "City9", 1), new NFLTeams("Team10", "City10", 2)},
                {new NFLTeams("Team11", "City11", 1), new NFLTeams("Team12", "City12", 0), new NFLTeams("Team13", "City13", 3), new NFLTeams("Team14", "City14", 2), new NFLTeams("Team15", "City15", 4)},
                {new NFLTeams("Team16", "City16", 2), new NFLTeams("Team17", "City17", 4), new NFLTeams("Team18", "City18", 1), new NFLTeams("Team19", "City19", 5), new NFLTeams("Team20", "City20", 3)},
                {new NFLTeams("Team21", "City21", 0), new NFLTeams("Team22", "City22", 2), new NFLTeams("Team23", "City23", 5), new NFLTeams("Team24", "City24", 3), new NFLTeams("Team25", "City25", 1)}
            };
    
            // Print out Team 17's Team info
            nflArray[3][1].displayTeamInfo();
            
            // Print out Team 21's Team Info
    
            nflArray[4][0].displayTeamInfo();
    
            // Print out Team 3's team Info
    
            nflArray[0][2].displayTeamInfo();
    
        }
    }
    NFLTeams2DArray.main(null)
    
    Team: Team17
    City: City17
    Championships: 4
    Team: Team21
    City: City21
    Championships: 0
    Team: Team3
    City: City3
    Championships: 1
    

    Updating 2D Arrays

    public class Update2DArray {
        public static void main(String[] args) {
            // Create a 3x3 2D array of integers
            int[][] matrix = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
    
            // Display the original 2D array
            System.out.println("Original 2D Array:");
            printArray(matrix);
    
            // Update specific elements in the array
            matrix[0][0] = 11;  // Update the element in the first row, first column
            matrix[1][1] = 22;  // Update the element in the second row, second column
            matrix[2][2] = 33;  // Update the element in the third row, third column
    
            // Display the updated 2D array
            System.out.println("\nUpdated 2D Array:");
            printArray(matrix);
        }
    
        // Helper method to print the 2D array
        public static void printArray(int[][] arr) {
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
    Update2DArray.main(null)
    
    
    Original 2D Array:
    1 2 3 
    4 5 6 
    7 8 9 
    
    Updated 2D Array:
    11 2 3 
    4 22 6 
    7 8 33 
    

    Popcorn HACK 3

    public class Update2DArrayHACK {
    
        // Helper method to print the 2D integer array
        public static void printIntArray(int[][] arr) {
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();
            }
        }
    
        public static void main(String[] args) {
    
            // Declare and Initialize a 2D integer array with the same dimensions (5x5)
            int[][] integerArray = {
                {1, 2, 3, 4, 5},
                {6, 7, 8, 9, 10},
                {11, 12, 13, 14, 15},
                {16, 17, 18, 19, 20},
                {21, 22, 23, 24, 25}
            };
    
         // Update the element in the first row, first column to 250
         integerArray[0][0] = 250;  
         // Update the element in the third row, third column to 69
         integerArray[2][2] = 69;  
    
         // Update the element in the fifth row, fifth column to 96
         integerArray[4][4] = 96;  
    
        // Update the element in the first row, fifth column to 125
        integerArray[0][4] = 125;  
         // Update the element in the second row, third column to 135        
         integerArray[1][2] = 135;  
            // Display the updated 2D integer array
            printIntArray(integerArray);
        }
    }
    Update2DArrayHACK.main(null)
    
    250 2 3 4 125 
    6 7 135 9 10 
    11 12 69 14 15 
    16 17 18 19 20 
    21 22 23 24 96 
    

    Popcorn HACK 4 - Review Quiz

    What is a 2D array?
    A. A single row of elements.
    B. A data structure with rows and columns.
    C. A list of 2 elements.
    D. A binary representation of data.
    
    ANS: B
    
    How do you declare a 2D array in Java?
    A. int myArray = new int[3][3];
    B. 2DArray myArray = new 2DArray[3][3];
    C. int[][] myArray;
    D. myArray = declare 2D array;
    
    ANS: C
    
    How do you access an element in a 2D array at row 2 and column 3?
    A. myArray[3][2]
    B. myArray[2][3]
    C. myArray[1][2]
    D. myArray[2][1]
    
    ANS: C
    
    What is the purpose of initializing a 2D array?
    A. To specify its data type.
    B. To allocate memory for the array.
    C. To access its elements.
    D. To declare the number of rows and columns.
    
    ANS: D
    
    In a 2D array, what does myArray[2][3] represent?
    A. The element in the second row and third column.
    B. The element in the third row and second column.
    C. The element in the third row and third column.
    D. The element in the second column and third row.
    
    ANS: the element is the third row and the FOURTH column 
    
    
    What happens when you update an element in a 2D array in Java?
    A. The entire array is cleared.
    B. Only the updated element is affected.
    C. The entire row is shifted.
    D. The element is removed from the array.
    
    ANS: B
    
    Which of the following represents a 2D array with 4 rows and 3 columns in Java?
    A. int[4][3] myArray;
    B. myArray[4,3] = int;
    C. int[3][4] myArray;
    D. myArray[3][4] = int;
    

    ANS: C

    HACKS

    Finish Popcorn HACKS, type DONE Here when you finish

    Done

    HACK 1

    // HACK 1 ANSWER
    
    public class TwoDArrayHack1 {
        public static void main(String[] args) {
            int rows = 5; 
            int columns = 4;
            int[][] Array = {
      
    
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13,14, 15, 16},
                {17,18, 19, 20}
    
            };
            for (int i = 0; i < Array.length; i++) {  
                    for (int j = 0; j < Array[i].length; j++) {
                        System.out.print(Array[i][j] + " ");
                    }
                    System.out.println();
                }
            }
        }
    
    TwoDArrayHack1.main(null);
    
    
    1 2 3 4 
    5 6 7 8 
    9 10 11 12 
    13 14 15 16 
    17 18 19 20 
    

    experimental version which uses methods to accomplish the same feat

    public class TwoDArrayHack1 {
        public static void main(String[] args) {
            int rows = 5;
            int columns = 4;
            TwoDArray array = new TwoDArray(rows, columns);
            
            array.setData(0, 0, 1);
            array.setData(0, 1, 2);
            array.setData(0, 2, 3);
            array.setData(0, 3, 4);
            array.setData(1, 0, 5);
            array.setData(1, 1, 6);
            array.setData(1, 2, 7);
            array.setData(1, 3, 8);
            array.setData(2, 0, 9);
            array.setData(2, 1, 10);
            array.setData(2, 2, 11);
            array.setData(2, 3, 12);
            array.setData(3, 0, 13);
            array.setData(3, 1, 14);
            array.setData(3, 2, 15);
            array.setData(3, 3, 16);
            array.setData(4, 0, 17);
            array.setData(4, 1, 18);
            array.setData(4, 2, 19);
            array.setData(4, 3, 20);
            
            array.printData();
        }
    }
    
    class TwoDArray {
        private int[][] data;
        
        public TwoDArray(int rows, int columns) {
            data = new int[rows][columns];
        }
        
        public void setData(int row, int col, int value) {
            data[row][col] = value;
        }
        
        public void printData() {
            for (int i = 0; i < data.length; i++) {
                for (int j = 0; j < data[i].length; j++) {
                    System.out.print(data[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
    
    TwoDArrayHack1.main(null);
    
    1 2 3 4 
    5 6 7 8 
    9 10 11 12 
    13 14 15 16 
    17 18 19 20 
    

    8.2

    Traversing

    public class ArrayTraversalExample {
        public static void main(String[] args) {
            // Array that is created in order to be traversed/itterate through
            int[] numbers = {1, 2, 3, 4, 5};
    
            // Traverse the array and print each element
            // How this works: 1. First it sets i to 0 in order to keep track of the index by using a for loop
            // Then it checks if the number is greater index if so then it will continue
            // uses i++ to continue to go through the indicies 
            // prints outs the number if greater than index
            for (int i = 0; i < numbers.length; i++) {
                System.out.println("Element at index " + i + " is: " + numbers[i]);
            }
        }
    }
    ArrayTraversalExample.main(null)
    
    Element at index 0 is: 1
    Element at index 1 is: 2
    Element at index 2 is: 3
    Element at index 3 is: 4
    Element at index 4 is: 5
    

    Nested For Loop

    public class NestedLoops {
        public static void main(String[] args) {
            for (int outer = 1; outer < 5; outer++) {
                for (int inner = 1; inner < 3; inner++) {
                    System.out.print(inner + " ");
                }
                System.out.println();
            }
        }
    }
    NestedLoops.main(null)
    
    1 2 
    1 2 
    1 2 
    1 2 
    

    Enhanced For Loop

    public class EnhancedForLoopExample {
        public static void main(String[] args) {
            String[] fruits = {"Apple", "Banana", "Cherry", "Date", "Fig"};
    
            // Here you use a en enhanced for loop to itterate through the array of strings
            for (String fruit : fruits) {
                System.out.println(fruit);
            }
        }
    }
    EnhancedForLoopExample.main(null)
    
    Apple
    Banana
    Cherry
    Date
    Fig
    

    Cumulative Knowledge

    ANS: traverse means to travel, in this case travelling through the 2d array

    ANS: its a loop in a loop

    ANS: its a special for loop that goes through each item without need of intitializing value and incrementing it

    Nested Loops traversing through a 2D Array

    public class TwoDArrayTraversal {
        public static void main(String[] args) {
            // First Create the 2D array
            int[][] twoDArray = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
            
            // Using a Nested loops to traverse the 2D array
            for (int row = 0; row < 3; row++) {
                for (int col = 0; col < 3; col++) {
                    int element = twoDArray[row][col];
                    System.out.print(element + " ");
                }
                System.out.println(); 
            }
        }
    }
    TwoDArrayTraversal.main(null)
    
    1 2 3 
    4 5 6 
    7 8 9 
    

    Popcorn Hack

    ANS: we replace it with the length

    public class TwoDArrayTraversal {
        public static void main(String[] args) {
            // First Create the 2D array
            int[][] twoDArray = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
            
            // Using a Nested loops to traverse the 2D array
            for (int row = 0; row < twoDArray.length; row++) { //grid makes sense becuase it gives you dimension
                for (int col = 0; col < twoDArray[row].length; col++) { // colliumn makes senseas it starts at 0 
                    int element = twoDArray[row][col];
                    System.out.print(element + " ");
                }
                System.out.println(); 
            }
        }
    }
    TwoDArrayTraversal.main(null)
    
    1 2 3 
    4 5 6 
    7 8 9 
    

    Practice

    public class Practice {
        public static void main(String[] args) {
    
            int[][] complexIntArray = {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12}
            };
    
           // MISSING CODE HERE 
           for (int row = 0; row < complexIntArray.length; row++) { 
            for (int col = 0; col < complexIntArray[row].length; col++) { //nested for loop
                int element = complexIntArray[row][col];
                System.out.print(element + " ");
            }
            System.out.println(); 
        }
    
          }
        }
        Practice.main(null);
    
    1 2 3 4 
    5 6 7 8 
    9 10 11 12 
    

    Using Enhanced For- Loops to Traverse an Array

    public class EnhancedForLoop2DArray {
        public static void main(String[] args) {
            // Define and initialize a 2D array
            int[][] twoDArray = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
    
            // Use nested enhanced for loops to traverse the 2D array
            for (int[] row : twoDArray) {
                for (int element : row) {
                    System.out.print(element + " ");
                }
                System.out.println(); // Move to the next row
            }
        }
    }
    EnhancedForLoop2DArray.main(null)
    
    1 2 3 
    4 5 6 
    7 8 9 
    

    Row Major Order Vs Column Major Order

    ANS: row major means that we put our elemments across, and in column the order would be going down

    1, 2, 3
    4, 5, 6
    7, 8, 9 (row major)
    1, 4, 7
    2, 5, 8
    3, 6, 9 (column major)
    public class PrintArray {
        public static void printArray(String[][] grid) {
            for (int row = 0; row < grid.length; row++) {
                for (int col = 0; col < grid[0].length; col++) {
                    System.out.print(grid[row][col] + " ");
                }
                System.out.println(); 
            }
        }
    
        public static void main(String[] args) {
            String[][] myGrid = {
                {"A", "B", "C"},
                {"D", "E", "F"},
                {"G", "H", "I"}
            };
            printArray(myGrid);
        }
    }
    PrintArray.main(null)
    
    A B C 
    D E F 
    G H I 
    
    public class PrintArray {
        public static void printArray(String[][] grid) {
            for (int col = 0; col < grid[0].length; col++) // outer loop for collums switched
            { for (int row = 0; row < grid.length; row++) //notice the outer is switched with the inner loop for rows
                 {
                    System.out.print(grid[row][col] + " ");
                }
                System.out.println(); 
            }
        }
    
        public static void main(String[] args) {
            String[][] myGrid = {
                {"A", "B", "C"},
                {"D", "E", "F"},
                {"G", "H", "I"}
            };
            printArray(myGrid);
        }
    }
    PrintArray.main(null)
    
    A D G 
    B E H 
    C F I 
    

    Practice

    public class PrintArray {
        public static void printArray(String[][] grid) {
            
            for (int col = 0; col < grid[0].length; col++) {
                for (int row = 0; row < grid.length; row++) {
    
                    System.out.print(grid[row][col] + " ");
                }
            }
        }
    
        public static void main(String[] args) {
            String[][] message = {
                {"My", "Ap", "Cs", "R"},
                {"AP", "A", "Class", "o"},
                {"C", "p", " ", "c"},
                {"S", " ", " ", "k"},
                {"s", " ", "s", "!"},
            };
    
            printArray(message);
        }
    }
    
    
    PrintArray.main(null)
    
    // how are you supposed to print out exactly My AP CS A Class Rocks?
    
    My AP C S s Ap A p     Cs Class     s R o c k ! 
    

    Algorithms That use 2D Arrays Traversing

    public class SearchExample {
        public static boolean search(String[][] chart, String name) {
            for (int r = 0; r < chart.length; r++) {
                for (int c = 0; c < chart[0].length; c++) {
                    if (chart[r][c].equals(name)) {
                        return true;
                    }
                }
            }
            return false; // Name not found in the array
        }
    
        public static void main(String[] args) {
            String[][] chart = {
                {"Alice", "Bob", "Charlie"},
                {"David", "Eve", "Frank"},
                {"Grace", "Hannah", "Isaac"}
            };
    
            String nameToSearch = "Krishiv";
            boolean found = search(chart, nameToSearch);
    
            if (found) {
                System.out.println(nameToSearch + " is in the array.");
            } else {
                System.out.println(nameToSearch + " is not in the array.");
            }
        }
    }
    SearchExample.main(null)
    
    Krishiv is not in the array.
    

    Hacks 8.2

    // MAIN HACK
    
    
    //  Traversing through 2D Array using a nested enhanced for loop
    public class TwoDArray {
        public static void main(String[] args) {
            // Define and initialize a 2D array to store fruits
            String[][] twoDArray = {
                {"Apple", "Banana", "Cherry"},
                {"Date", "Fig", "Grape"},
                {"Lemon", "Mango", "Orange"}
            };
    
            // Use nested enhanced for loops to traverse the 2D array and print the fruits
            for (String[] row : twoDArray) {
                for (String fruit : row) {
                    System.out.print(fruit + " ");
                }
                System.out.println();
            }
        }
    }
    
    TwoDArray.main(null);
    
    
    
    Apple Banana Cherry 
    Date Fig Grape 
    Lemon Mango Orange 
    
    // Column major order traversal
    public class ColumnMajorTraversal {
        public static void printArray(String[][] grid) {
            // Outer loop for columns (major order)
            for (int col = 0; col < grid[0].length; col++) {
                // Inner loop for rows (minor order)
                for (int row = 0; row < grid.length; row++) {
                    System.out.print(grid[row][col] + " ");
                }
                System.out.println(); // Print a new line for each column
            }
        }
    
        public static void main(String[] args) {
            String[][] myGrid = {
                {"A", "D", "G"},
                {"B", "E", "H"},
                {"C", "F", "I"}
            };
            printArray(myGrid);
        }
    }
    
    ColumnMajorTraversal.main(null);
    
    
    A B C 
    D E F 
    G H I 
    

    Create your own situration of an Algorthm that needs to traverse a 2D array and then write the code for it

    Scenario: After you proved your ability to traverse through 1d arrays to the cartel, with your hitlist traversal, the cartel gives you another question in your deadly technical interview. You must now traverse through a 2d array storing different types of guns, and print out items from the 2d array that are chambered in 9mm rounds. You can use any method of traversal, and success will allow you to survive and potentially work for the cartel.

    public class cartelGuns {
    
        // This method prints the contents of a 2D array, row by row.
        public static void printArray(String[][] grid) {
            for (int row = 0; row < grid.length; row++) {
                for (int col = 0; col < grid[0].length; col++) {
                    System.out.print(grid[row][col] + " ");
                }
                System.out.println(); // Move to the next row after printing a row.
            }
        }
    
        // This method prints only the guns that contain "9mm" in their names from the 2D array.
        public static void print9mmGuns(String[][] grid) {
            for (int row = 0; row < grid.length; row++) {
                for (int col = 0; col < grid[0].length; col++) {
                    if (grid[row][col].contains("9mm")) {
                        System.out.println(grid[row][col]); // Print the gun name.
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            // Define a 2D array containing gun names and their calibers.
            String[][] guns = {
                {"9mm: glock", "12 gauge: riot shotgun", "7.62x25mm: calibrated pistol"},
                {"5.56x45mm: assault rifle", "0000", "0000"},
                {"9mm: uzi", "10mm: submachine gun", "gernade launcher"}
            };
    
            System.out.println("All Guns:");
            // Call the printArray method to print all guns in the array.
            printArray(guns);
    
            System.out.println("\n9mm Chambered Guns:");
            // Call the print9mmGuns method to print only the guns chambered in 9mm.
            print9mmGuns(guns);
        }
    }
    
    
    cartelGuns.main(null);
    
    
    All Guns:
    9mm: glock 12 gauge: riot shotgun 7.62x25mm: calibrated pistol 
    5.56x45mm: assault rifle 0000 0000 
    9mm: uzi 10mm: submachine gun gernade launcher 
    
    9mm Chambered Guns:
    9mm: glock
    9mm: uzi
    

    Image Representation with 2D Arrays

    Digital images are essentially a collection of small, discrete elements called pixels. Pixels are organized in a 2D grid, where each pixel represents a single point of color or intensity. Each element (pixel) in the 2D array corresponds to one pixel in the image. In a color image, each pixel contains three color components: Red, Green, and Blue (RGB), while in grayscale images, each pixel has a single intensity value.

    Traversing and Processing an Image

    Traversing an image’s 2D array involves systematically visiting every pixel in the image grid. This process often uses nested loops, with the outer loop iterating over the rows and the inner loop iterating over the columns. By traversing the array, you gain access to each pixel’s information, such as color values or intensity. This structured access is fundamental for various image processing tasks.

    import java.io.*;
    import java.net.URL;
    import javax.imageio.ImageIO; // ImageIO is a class in Java libraries which gives an easy way to use different image formats
    import java.awt.image.BufferedImage; // BufferedImage is a class in Java libraries to help perform operations on images (read + write)
    
    public class ImageProcessing {
        public static void main(String[] args) {
            String imageUrl = "https://user-images.githubusercontent.com/111609656/277895130-d15b0768-01d9-4522-8ef7-4f8bcf69c42e.png";
            String outputFolder = "../images";
            String customFileName = "MORT1.png"; 
    
            try {
                String outputPath = outputFolder + File.separator + customFileName;
    
                URL url = new URL(imageUrl); // create URL object
    
                try (InputStream in = url.openStream();   // try-catch block where errors are handled
                     OutputStream out = new FileOutputStream(outputPath)) {   // input stream reads data and output stream writes the data
    
                    byte[] buffer = new byte[1024];
                    int bytesRead;
    
                    while ((bytesRead = in.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }   // reading the data from the URL and writes in 1024 byte chunks
                }
    
                System.out.println("Image downloaded and saved to: " + outputPath);
    
                File imageFile = new File(outputPath);
                BufferedImage image = ImageIO.read(imageFile); 
                int width = image.getWidth();
                int height = image.getHeight();   // get the image dimensions
    
                System.out.println("Success! Image Dimensions (Width x Height): " + width + " x " + height);
    
                // Process the image using a 2D array
                int[][] pixels = new int[width][height];
    
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        int pixel = image.getRGB(x, y);
                        // Process the pixel here, e.g., apply filters or transformations
                        pixels[x][y] = pixel;
                    }
                }
    
                // Calculate resolution in pixels per inch (PPI)
                int ppi = (int) (image.getWidth() / (width * 0.0254));
                System.out.println("Resolution: " + ppi + " pixels per inch (PPI)");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ImageProcessing.main(null)
    
    Image downloaded and saved to: ../images/MORT1.png
    Success! Image Dimensions (Width x Height): 1030 x 1372
    Resolution: 39 pixels per inch (PPI)
    

    Grayscale Conversion with Images

    Grayscale conversion is a fundamental image processing operation. When converting an image to grayscale, you effectively remove color information and retain only the pixel intensity. This is typically done by calculating the average intensity from the RGB components of each pixel. The result is a grayscale image where variations in pixel intensity represent the image’s features and details. This operation can serve as a starting point for more complex image processing techniques.

    import java.awt.image.BufferedImage;
    import java.awt.image.ColorConvertOp;
    import java.io.*;
    import java.net.URL;
    import javax.imageio.ImageIO;
    
    public class ImageToGrayscaleWithArray {
        public static void main(String[] args) {
            String imageUrl = "https://user-images.githubusercontent.com/111609656/277895164-5f93f1d8-88b5-4b08-b9a1-b54fb6d55d96.png"; // Replace with the actual image URL
            String outputFolder = "../images";
            String customFileName = "MORT2_Grayscale.png"; // Change this to your desired file name for the grayscale image
    
            try {
                // Define the output file path
                String outputPath = outputFolder + File.separator + customFileName;
    
                // Create a URL object from the image URL
                URL url = new URL(imageUrl);
    
                // Open a connection to the URL and get the input stream
                try (InputStream in = url.openStream();
                     OutputStream out = new FileOutputStream(outputPath)) {
    
                    // Read data from the URL and save it to the output file
                    byte[] buffer = new byte[1024];
                    int bytesRead;
    
                    while ((bytesRead = in.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                }
    
                // Read the downloaded image
                BufferedImage originalImage = ImageIO.read(new File(outputPath));
                int width = originalImage.getWidth();
                int height = originalImage.getHeight();
    
                // Create a 2D array to store grayscale values
                int[][] grayscaleArray = new int[width][height];
    
                // Convert the image to grayscale and populate the array
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        int pixel = originalImage.getRGB(x, y);
                        int red = (pixel >> 16) & 0xFF;
                        int green = (pixel >> 8) & 0xFF;
                        int blue = pixel & 0xFF;
                        int gray = (red + green + blue) / 3;
                        grayscaleArray[x][y] = gray;
                    }
                }
    
                // Save the grayscale image
                String grayscaleOutputPath = outputFolder + File.separator + customFileName;
                BufferedImage grayscaleImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        int grayValue = grayscaleArray[x][y];
                        int grayPixel = (grayValue << 16) | (grayValue << 8) | grayValue;
                        grayscaleImage.setRGB(x, y, grayPixel);
                    }
                }
    
                ImageIO.write(grayscaleImage, "png", new File(grayscaleOutputPath));
    
                System.out.println("Success! Image converted to grayscale, downloaded, and saved to: " + grayscaleOutputPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ImageToGrayscaleWithArray.main(null)
    
    Success! Image converted to grayscale, downloaded, and saved to: ../images/MORT2_Grayscale.png
    

    Image Conversion


    Why do we Convert Images ?

    ANS: images have different purposes for each format, and it could help with writing image data, if we want to also change the image along with the conversion.

    How Does Image Conversion Work:

    import javax.imageio.ImageIO; // allows you to read and write images in various formats.
    import java.io.File; // allows you to work with files and directories in your file system.
    import java.io.IOException; // allows you to handle input and output exceptions that may occur during file operations.
    import java.awt.image.BufferedImage; // allows you to work with images stored in memory, providing methods to manipulate image data.
    
    public class ImageConverter {
    
        public static void main(String[] args) {
            try {
                // Input and output file paths
                String[] inputPaths = {
                    "/Users/nikhilchakravarthula/vscode/KPNSLESSON/images/woodworker_mort.png",
                    "/Users/nikhilchakravarthula/vscode/KPNSLESSON/images/Mort2.png"
                };
                String outputPath = "/Users/nikhilchakravarthula/vscode/KPNSLESSON/imagesConvert";
    
                // Loop through each image in the array
                for (String inputPath : inputPaths) {
                    // Read the image
                    File inputFile = new File(inputPath);
                    BufferedImage img = ImageIO.read(inputFile);  // Buffered image is a class in java for handling image data
    
                    // Write the image
                    String outputFileName = "converted_" + new File(inputPath).getName().replace(".png", ".gif");
                    String outputFilePath = outputPath + File.separator + outputFileName;
                    File outputFile = new File(outputFilePath);
                    ImageIO.write(img, "gif", outputFile);
    
                    System.out.println("Image conversion successful for: " + inputPath);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ImageConverter.main(null)
    
    
    javax.imageio.IIOException: Can't read input file!
    	at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
    	at REPL.$JShell$69$ImageConverter.main($JShell$69.java:37)
    	at REPL.$JShell$70.do_it$($JShell$70.java:21)
    	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    	at io.github.spencerpark.ijava.execution.IJavaExecutionControl.lambda$execute$1(IJavaExecutionControl.java:95)
    	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    	at java.base/java.lang.Thread.run(Thread.java:1623)
    
    import javax.imageio.ImageIO;
    import java.io.File;
    import java.io.IOException;
    import java.awt.image.BufferedImage;
    
    public class ImageConverter {
    
        public static void main(String[] args) {
            try {
                // Input and output file paths
                String inputPath = "/mnt/c/Users/super/vscode/getsums/images/MORT1.png";
                String outputPath = "/mnt/c/Users/super/vscode/getsums/images";
    
                // Read the PNG image
                BufferedImage img = ImageIO.read(new File(inputPath));
    
                // Convert image to RGB format 
                BufferedImage rgbImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
                rgbImage.createGraphics().drawImage(img, 0, 0, null);
    
                // Define the output file name and path
                String outputFileName = inputPath.substring(inputPath.lastIndexOf("/") + 1).replace(".png", ".jpeg");
                String outputFilePath = outputPath + File.separator + outputFileName;
    
                // Convert and save the image as JPEG
                ImageIO.write(rgbImage, "jpeg", new File(outputFilePath));
    
                System.out.println("Image conversion successful!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    ImageConverter.main(null);
    
    
    Image conversion successful!
    

    Scaling the Image

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    public class ImageScaler {
    
        public static void main(String[] args) {
            try {
                // Input and output file paths
                String inputPath = "/Users/nikhilchakravarthula/vscode/KPNSLESSON/images/snow_mort.png";
                String outputPath = "/Users/nikhilchakravarthula/vscode/KPNSLESSON/imagesConvert";
    
                // Desired width and height of the scaled image
                int scaledWidth = 100;
                int scaledHeight = 100;
    
                // Read the image
                File inputFile = new File(inputPath);
                BufferedImage inputImage = ImageIO.read(inputFile);
    
                // Scale the image
                BufferedImage scaledImage = scaleImage(inputImage, scaledWidth, scaledHeight);
    
                // Write the scaled image
                String outputFileName = "scaled_" + new File(inputPath).getName();
                String outputFilePath = outputPath + File.separator + outputFileName;
                File outputFile = new File(outputFilePath);
                ImageIO.write(scaledImage, "png", outputFile);  
    
                System.out.println("Image scaling successful!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static BufferedImage scaleImage(BufferedImage originalImage, int scaledWidth, int scaledHeight) {
            // Create a new BufferedImage with the desired width and height
            BufferedImage scaledImage = new BufferedImage(scaledWidth, scaledHeight, originalImage.getType());
        
            // g2d more into
            // Create a Graphics2D object and set the rendering hints for scaling
            Graphics2D g2d = scaledImage.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        
            // Draw the original image on the new BufferedImage with the desired width and height
            g2d.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
        
            // Dispose of the Graphics2D object
            g2d.dispose();
        
            return scaledImage;
        }
    }
    
    ImageScaler.main(null);
    
    
    javax.imageio.IIOException: Can't read input file!
    	at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
    	at REPL.$JShell$73$ImageScaler.main($JShell$73.java:37)
    	at REPL.$JShell$74.do_it$($JShell$74.java:23)
    	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    	at io.github.spencerpark.ijava.execution.IJavaExecutionControl.lambda$execute$1(IJavaExecutionControl.java:95)
    	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    	at java.base/java.lang.Thread.run(Thread.java:1623)
    

    Images Hack

    Hack: Create a functioning code in which you convert a PNG image to a JPEG image (make it funny).

    import javax.imageio.ImageIO;
    import java.io.File;
    import java.io.IOException;
    import java.awt.image.BufferedImage;
    
    public class ImageConverter {
    
        public static void main(String[] args) {
            try {
                // Input and output file paths
                String inputPath = "/home/finnc/vscode/stud/images/cad.png";
                String outputPath = "/home/finnc/vscode/stud/images/";
    
                // Read the PNG image
                BufferedImage img = ImageIO.read(new File(inputPath));
    
                // Create a new BufferedImage with the same dimensions and type
                BufferedImage modifiedImage = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
    
                // Modify the colors by iterating through each pixel
                for (int y = 0; y < img.getHeight(); y++) {
                    for (int x = 0; x < img.getWidth(); x++) {
                        int rgb = img.getRGB(x, y);
                        int alpha = (rgb >> 24) & 0xFF;
                        int red = (rgb >> 16) & 0xFF;
                        int green = (rgb >> 8) & 0xFF;
                        int blue = rgb & 0xFF;
    
                        // Add 20 to the red value (clamp to 255)
                        red = Math.min(255, red + 120);
    
                        int newRGB = (alpha << 24) | (red << 16) | (green << 8) | blue;
                        modifiedImage.setRGB(x, y, newRGB);
                    }
                }
    
                // Define the output file name and path
                String outputFileName = inputPath.substring(inputPath.lastIndexOf("/") + 1).replace(".png", "_modified.png");
                String outputFilePath = outputPath + File.separator + outputFileName;
    
                // Save the modified image as a PNG file
                ImageIO.write(modifiedImage, "jpeg", new File(outputFilePath));
    
                System.out.println("Image modification successful!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    ImageConverter.main(null);
    
    Image modification successful!
    

    the png

    image.png

    the jpeg

    image.jpeg

    Grading for Hacks