You are about to write Java programs to process real images. In general, there are two types of processing: single pixel-based manipulation and filter-based manipulation. The former just needs the pixel information at a pixel location whereas the latter requires the pixel information at a pixel location and its adjacent pixels. Some processed sample images can be found at here. Also, this page shows some sample images with blurry effect.
class Pixel { //Private data fields (instance variables) private int value; //This 32-int integer contains four 8-bit integers for opacity, red, green, and blue. private int row; private int col; //If a pixel value is beyond the range 0-255, //"normalize" it to the border value 0 or 255. //For example, use the class name to call the normalize() method: Pixel.normalize(-13) = 0. //Pixel.normalize(278) = 255. public static int normalize(double p) { return (int)((p < 0)?0:((p > 255)?255:p)); } //Below are public methods including constructors // ... }
class Image { private int rows; private int cols; private Pixel [][] pixels; //Constructor. arr is a 2D array of pixel values. r: rows; c: columns public Image(int [][] arr, int r, int c) { //Create a 2D array of Pixel objects (of type Pixel) pixels = new Pixel[r][c]; rows = r; cols = c; //Use pixel values in arr to create Pixel objects at each location for(int i = 0; i< r; i++) for(int j = 0; j < c; j++) pixels[i][j] = new Pixel(arr[i][j], i, j); } //Below are other member methods // .... }In the Image class, add the following image processing methods:
1/9 | 1/9 | 1/9 |
1/9 | 1/9 | 1/9 |
1/9 | 1/9 | 1/9 |
p[i][j] = (p[i-1][j-1]+p[i-1][j]+p[i-1][j+1]+p[i][j-1]+p[i][j]+p[i][j+1]+p[i+1][j-1]+p[i+1][j]+p[i+1][j+1])/9This can also be done easily by using double loops like:
int [][] filter = {{1.0/9.0, 1.0/9.0, 1.0/9.0}, {1.0/9.0, 1.0/9.0, 1.0/9.0}, {1.0/9.0, 1.0/9.0, 1.0/9.0} }; for (int ii = -1; ii < 2; ii++) for (int jj = -1; jj < 2; jj++) p[i][j] += filter[ii+1][jj+1] * p[i + ii][j + jj]; where ii and jj are offsets from the coordinates of the pixel being processed.For the emboss(), the filter has weights like:
-2 | -1 | 0 |
-1 | 1 | 1 |
0 | 1 | 2 |
int [][] filter = {{-2, -1, 0}, {-1, 1, 0}, {0, 1, 2} }; for (int ii = -1; ii < 2; ii++) for (int jj = -1; jj < 2; jj++) p[i][j] += filter[ii+1][jj+1] * p[i + ii][j + jj]; where ii and jj are offsets from the coordinates of the pixel being processed.
Sample main method in the ImageProc class (driver)
//Driver Class for Image Processing public class ImageProc{ public static void main(String args[])throws IOException{ //The user enters input, output image files and the type of operation through command line arguments if(args.length == 0){ System.out.println("Missing input, output file names and the type of operation"); } String inputFile = args[0]; String outputFile = args[1]; String op = args[2]; System.out.println("Input image file: " + inputFile); System.out.println("Output image file: " + outputFile); System.out.println("What operation do you want to perform: " + op); //Extract pixel values from a real image file and return to a 2D integer array int [][] arr = extract(inputFile); //Create an Image object Image image = new Image(arr, arr.length, arr[0].length); //Operation menu switch(op) { case "grayscale": image.grayscale(); break; case "invert": image.invert(); break; case "add_bars": image.addBars(); break; case "blur": image.blur(); break; case "emboss": image.emboss(); break; } //Get pixel values (a 2D array of integers) from the Image object arr = image.getPixels(); //Create a real output image file with pixel values from the Image object write(arr, outputFile); System.out.println("Image Processing is complete!"); } }
Sample command line:
C:\Users\yzhang\ImageProc>javac ImageProc.java C:\Users\yzhang\ImageProc>java ImageProc model.jpg model_invert.jpg invert Input image file: model.jpg Output image file: model_invert.jpg What operation do you want to perform: invert Image Processing is complete!