You are about to write Java programs to process images. In general, there are two types of processing: single pixel-based manipulation and filter-based manipulation. The former 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 here. Also, this page shows some sample images with blurry effects.
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: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:
\[
\begin{bmatrix}
-2 & -1 & 0 \\
-1 & 1 & 1 \\
0 & 1 & 2
\end{bmatrix}
\]
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 lines for execution below. Alternatively, you can use a Scanner object to get input from the user.
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!