Question: Rotational Transformations These are conceptually quite straight-forward, as shown in the test cases below. Rotate Clockwise and Rotate Counter-Clockwise There is a major wrinkle with
Rotational Transformations
These are conceptually quite straight-forward, as shown in the test cases below.
Rotate Clockwise and Rotate Counter-Clockwise
There is a major wrinkle with these two transforms. The implementation of PixelImage requires that when the setData method is called, the dimensions of the array of Pixels matches the original dimensions of the image. Therefore, these transformations can only be applied to square images. If the Pixel array does not have the same dimensions, the call to setData fails with an IllegalArgumentException.
The implementation of these filters needs to deal with the requirement for a square image. If the image is square, the filter should apply the rotational transform. If the image is not square, there is no need to do any processing; the filter can raise IllegalStateException. The SnapShop code is set up to handle this exception displaying a message dialog box, which will display the exception message.
I need to create two .java files: RotateClockwiseFilter.java and RotateCounterClockwiseFilter.java. The code must include
public class RotateCounterClockwiseFilter implements Filter { public void filter(PixelImage theImage) { // get the data from the image Pixel[][] data = theImage.getData();
to be able to edit the image. I've included PixelImage.java which may help
import java.awt.image.*;
public class PixelImage { private BufferedImage myImage; private int width; private int height;
/** * Construct a PixelImage from a Java BufferedImage * @param bi The image */ public PixelImage(BufferedImage bi) { // initialise instance variables this.myImage = bi; this.width = bi.getWidth(); this.height = bi.getHeight(); }
/** * Return the width of the image */ public int getWidth() { return this.width; }
/** * Return the height of the image */ public int getHeight() { return this.height; }
/** * Return the image's pixel data as an array of Pixels. * @return The array of pixels */ public Pixel[][] getData() {
/* The Raster has origin 0,0 , so the size of the * array is [width][height], where width and height are the * dimensions of the Raster */ Raster r = this.myImage.getRaster(); Pixel[][] data = new Pixel[r.getHeight()][r.getWidth()]; int[] samples = new int[3];
// Translates from java image data to Pixel data for (int row = 0; row < r.getHeight(); row++) { for (int col = 0; col < r.getWidth(); col++) { r.getPixel(col, row, samples); Pixel ourPixel = new Pixel(samples[0], samples[1], samples[2]); data[row][col] = ourPixel; } } return data; }
/** * Set the image's pixel data from an array. This array must match * that returned by getData() in terms of dimensions. * @param data The array to pull from * @throws IllegalArgumentException if the passed in array does not match * the dimensions of the PixelImage or has pixels with invalid values */
public void setData(Pixel[][] data) throws IllegalArgumentException { WritableRaster wr = this.myImage.getRaster();
if (data.length != wr.getHeight()) { throw new IllegalArgumentException("Array size does not match"); } else if (data[0].length != wr.getWidth()) { throw new IllegalArgumentException("Array size does not match"); }
// Translates from an array of Pixel data to java image data for (int row = 0; row < wr.getHeight(); row++) { for (int col = 0; col < wr.getWidth(); col++) { wr.setPixel(col, row, data[row][col].rgb); } } }
/** * IGNORE THIS METHOD -- you won't need it */ public BufferedImage getImage() { return this.myImage; } }
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
