import java.awt.*; import java.awt.font.*; import java.awt.geom.*; import java.text.*; import java.awt.image.BufferedImage; import java.util.*; import java.util.List; // resolves problem with java.awt.List and java.util.List /** * A class that represents a picture. This class inherits from * SimplePicture and allows the student to add functionality to * the Picture class. * * Copyright Georgia Institute of Technology 2004 * @author Barbara Ericson ericson@cc.gatech.edu */ public class Picture extends SimplePicture { ///////////////////// constructors ///////////////////////////////// /** * Constructor that takes no arguments */ public Picture () { /* not needed but use it to show students the implicit call to * super() child constructors always call a parent constructor */ super(); } /** * Constructor that takes a file name and creates the picture * @param fileName the name of the file to create the picture from */ public Picture(String fileName) { // let the parent class handle this fileName super(fileName); } /** * Constructor that takes the width and height * @param width the width of the desired picture * @param height the height of the desired picture */ public Picture(int width, int height) { // let the parent class handle this width and height super(width,height); } /** * Constructor that takes a width and height for a new * picture and sets the color for the new picture * @param width the width of the desired picture * @param height the height of the desired picture * @param theColor the color for the background */ public Picture(int width, int height, Color theColor) { // let the parent class handle these parameters super(width,height,theColor); } /** * Constructor that takes a picture and creates a * copy of that picture */ public Picture(Picture copyPicture) { // let the parent class do the copy super(copyPicture); } /** * Constructor that takes a buffered image * @param image the buffered image to use */ public Picture(BufferedImage image) { super(image); } ////////////////////// methods ///////////////////////////////////// /** * Method to return a string with information about this picture. * @return a string with information about the picture such as * fileName, height, and width. */ public String toString() { String output = "Picture, filename " + this.getFileName() + " height " + this.getHeight() + " width " + this.getWidth(); return output; } /** * Method to decrease the red by half in the current picture */ public void decreaseRed() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int value = 0; int index = 0; // loop through all the pixels while(index < pixelArray.length) { // get the current pixel pixel = pixelArray[index]; // get the value value = pixel.getRed(); // decrease the red value by 50% (1/2) value = (int) (value * 0.5); // set the red value of the current pixel to the new value pixel.setRed(value); // increment the index index = index + 1; } } /** * Method to decrease red by the passed * percent * @param percent the percent to reduce by */ public void decreaseRed(int percent) { Pixel[] pixelArray = this.getPixels(); int red = 0; double factor = 1.0 - (percent / 10); // loop through all the pixels for (Pixel currPixel : pixelArray) { red = currPixel.getRed(); currPixel.setRed((int) (red * factor)); } } /** * Method to clear the blue from the picture (set * the blue to 0 for all pixels) */ public void clearBlue() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int index = 0; // loop through all the pixels while (index < pixelArray.length) { // get the current pixel pixel = pixelArray[index]; // set the blue on the pixel to 0 pixel.setBlue(0); // increment index index++; } } /** * Method to clear the red from a picture */ public void clearRed() { Pixel[] pixelArray = this.getPixels(); for (Pixel currPixel : pixelArray) { currPixel.setRed(0); } } /** * Method to clear the green from a picture */ public void clearGreen() { Pixel[] pixelArray = this.getPixels(); for (Pixel currPixel : pixelArray) { currPixel.setGreen(0); } } /** * Method to simulate a sunset by decreasing the green * and blue */ public void makeSunset() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int value = 0; int i = 0; // loop through all the pixels while (i < pixelArray.length) { // get the current pixel pixel = pixelArray[i]; // change the blue value value = pixel.getBlue(); pixel.setBlue((int) (value * 0.7)); // change the green value value = pixel.getGreen(); pixel.setGreen((int) (value * 0.7)); // increment the index i++; } } /** * Method to simulate a sunset by decreasing the green * and blue * @param factor the amount to multiply the original values by */ public void makeSunset(double factor) { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int value = 0; int i = 0; // loop through all the pixels while (i < pixelArray.length) { // get the current pixel pixel = pixelArray[i]; // change the blue value value = pixel.getBlue(); pixel.setBlue((int) (value * factor)); // change the green value value = pixel.getGreen(); pixel.setGreen((int) (value * factor)); // increment the index i++; } } /** * Method to change the red by an amount * @param amount the amount to change the red by */ public void changeRed(double amount) { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int value = 0; int i = 0; // loop through all the pixels while( i < pixelArray.length) { // get the current pixel pixel = pixelArray[i]; // get the value value = pixel.getRed(); /* set the red value to the original value * times the passed amount */ pixel.setRed((int) (value * amount)); // increment i i++; } } /** * Method to change the color of each pixel in the picture * object by passed in amounts. * @param redAmount the amount to change the red value * @param greenAmount the amount to change the green value * @param blueAmount the amount to change the blue value */ public void changeColors(double redAmount, double greenAmount, double blueAmount) { Pixel[] pixelArray = this.getPixels(); int value = 0; // loop through all the pixels for (Pixel pixel : pixelArray) { // change the red value value = pixel.getRed(); pixel.setRed((int) (redAmount * value)); // change the green value value = pixel.getGreen(); pixel.setGreen((int) (greenAmount * value)); // change the blue value value = pixel.getBlue(); pixel.setBlue((int) (blueAmount * value)); } } /** * Method to negate the pixels in the * current picture */ public void negate() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int redValue, blueValue, greenValue = 0; // loop through all the pixels for (int i = 0; i < pixelArray.length; i++) { // get the current pixel pixel = pixelArray[i]; // get the current red, green, and blue values redValue = pixel.getRed(); greenValue = pixel.getGreen(); blueValue = pixel.getBlue(); // set the pixel's color to the new color pixel.setColor(new Color(255 - redValue, 255 - greenValue, 255 - blueValue)); } } /** * Method to change the picture to gray scale */ public void grayscale() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int intensity = 0; // loop through all the pixels for (int i = 0; i < pixelArray.length; i++) { // get the current pixel pixel = pixelArray[i]; // compute the intensity of the pixel (average value) intensity = (int) ((pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3); // set the pixel color to the new color pixel.setColor(new Color(intensity,intensity,intensity)); } } /** * Method to change the picture to gray scale */ public void grayscale(int startX, int startY, int endX, int endY) { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int intensity = 0; // loop through x for (int x = startX; x < endX; x++) { for (int y = startY; y < endY; y++) { // get the current pixel pixel = this.getPixel(x,y); // compute the intensity of the pixel (average value) intensity = (int) ((pixel.getRed() + pixel.getGreen() + pixel.getBlue()) / 3); // set the pixel color to the new color pixel.setColor(new Color(intensity,intensity,intensity)); } } } /** * Method to change the picture to gray scale with luminance */ public void grayscaleWithLuminance() { Pixel[] pixelArray = this.getPixels(); Pixel pixel = null; int luminance = 0; double redValue = 0; double greenValue = 0; double blueValue = 0; // loop through all the pixels for (int i = 0; i < pixelArray.length; i++) { // get the current pixel pixel = pixelArray[i]; // get the corrected red, green, and blue values redValue = pixel.getRed() * 0.299; greenValue = pixel.getGreen() * 0.587; blueValue = pixel.getBlue() * 0.114; // compute the intensity of the pixel (average value) luminance = (int) (redValue + greenValue + blueValue); // set the pixel color to the new color pixel.setColor(new Color(luminance,luminance,luminance)); } } /** * Method to mirror around a vertical line in the middle * of the picture based on the width */ public void mirrorVertical() { int width = this.getWidth(); int mirrorPoint = width / 2; Pixel leftPixel = null; Pixel rightPixel = null; // loop through all the rows for (int y = 0; y < getHeight(); y++) { // loop from 0 to the middle (mirror point) for (int x = 0; x < mirrorPoint; x++) { leftPixel = getPixel(x, y); rightPixel = getPixel(width - 1 - x, y); rightPixel.setColor(leftPixel.getColor()); } } } /** * Method to mirror around a horizontal line in the middle * based on the height. It copies the top mirrored to * the bottom */ public void mirrorHorizontal() { int height = this.getHeight(); int mirrorPoint = height / 2; Pixel topPixel = null; Pixel bottomPixel = null; // loop through the columns for (int x=0; x < getWidth(); x++) { // loop from 0 to just before the mirror point for (int y=0; y < mirrorPoint; y++) { topPixel = getPixel(x,y); bottomPixel = getPixel(x,height - 1 - y); bottomPixel.setColor(topPixel.getColor()); } } } /** * Method to mirror around a horiztonal line in the middle * based on the height of the picture. It copies the bottom * to the top. */ public void mirrorHorizontalBottomToTop() { int height = this.getHeight(); int mirrorPoint = height / 2; Pixel topPixel = null; Pixel bottomPixel = null; // loop through the columns for (int x=0; x < getWidth(); x++) { // loop from 1 to just before the mirror point for (int y=0; y < mirrorPoint; y++) { topPixel = getPixel(x,y); bottomPixel = getPixel(x,height - 1 - y); topPixel.setColor(bottomPixel.getColor()); } } } /** * Mirror diagonal from 0,0 to width-1,height-1 */ public void mirrorDiagTopLeftBotRight() { Pixel leftPixel = null; Pixel rightPixel = null; for (int y = 1; y < this.getHeight(); y++) { for (int x = 0; x < y; x++) { leftPixel = this.getPixel(x,y); rightPixel = this.getPixel(y,x); rightPixel.setColor(leftPixel.getColor()); } } } /** * Method to mirror around a diagonal line * from width-1,0 to 0,height-1 */ public void mirrorDiagTopRightBotLeft() { Pixel leftPixel = null; Pixel rightPixel = null; int height = this.getHeight(); for (int y = height - 2; y >= 0; y--) { for (int x = 0; x < height - 1 -y; x++) { leftPixel = this.getPixel(x,y); rightPixel = this.getPixel(height-1-y, height - 1- x); rightPixel.setColor(leftPixel.getColor()); } } } /** * Method to mirror part of the temple picture around a * vertical line at a mirror point */ public void mirrorTemple() { int mirrorPoint = 276; Pixel leftPixel = null; Pixel rightPixel = null; int count = 0; // loop through the rows for (int y = 27; y < 97; y++) { // loop from 13 to just before the mirror point for (int x = 13; x < mirrorPoint; x++) { System.out.println("Copying color from " + x + " to " + (mirrorPoint + (mirrorPoint - x))); leftPixel = getPixel(x, y); rightPixel = getPixel(mirrorPoint + (mirrorPoint - x), y); rightPixel.setColor(leftPixel.getColor()); count = count + 1; } } System.out.println("We copied " + count + " pixels"); } /** * Method to mirror part of the temple picture around a * vertical line at a mirror point */ public void mirrorHorizontalRange(int startX, int endX, int startY, int endY, int mirrorX) { Pixel leftPixel = null; Pixel rightPixel = null; // loop through the rows for (int y = startY; y < endY; y++) { // loop from startX to just before the // mirror point: endX for (int x = startX; x < endX; x++) { leftPixel = getPixel(x, y); rightPixel = getPixel(mirrorX + (mirrorX - x), y); rightPixel.setColor(leftPixel.getColor()); } } } /** * Method to mirror part of the picture around a * horiztonal mirror * @param startX the start x of the range to mirror * @param endX the end x of the range to mirror * @param mirrorPoint the y value to mirror around */ public void mirrorHorizRange(int startX,int endX, int mirrorPoint) { Pixel topPixel = null; Pixel botPixel = null; int count = 0; // loop through the rows till the mirror point for (int y = 0; y < mirrorPoint; y++) { // loop from start to end of x range for (int x = startX; x < endX; x++) { topPixel = this.getPixel(x, y); botPixel = this.getPixel(x, this.getHeight() - 1 - y); botPixel.setColor(topPixel.getColor()); } } } /** * Method to mirror part of a picture around * a vertical mirror point */ public Picture mirrorVertRange(int mirrorPoint) { Pixel left = null; Pixel right = null; int resultWidth = (mirrorPoint + 1) * 2; Picture result = new Picture(resultWidth,this.getHeight()); Color resColor = null; for (int x =0; x <= mirrorPoint; x++) { for(int y = 0; y < this.getHeight(); y++) { left = this.getPixel(x,y); right = result.getPixel(resultWidth - 1 - x,y); resColor = left.getColor(); right.setColor(resColor); result.getPixel(x,y).setColor(resColor); } } return result; } /** * Method to copy the picture of Katie to the * upper left corner of the current picture */ public void copyKatie() { String sourceFile = FileChooser.getMediaPath("KatieFancy.jpg"); Picture sourcePicture = new Picture(sourceFile); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX=0; sourceX < sourcePicture.getWidth(); sourceX++, targetX++) { // loop through the rows for (int sourceY = 0, targetY =0; sourceY < sourcePicture.getHeight(); sourceY++, targetY++) { // set the target pixel color to the source pixel color sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy the picture of Katie to (100,100) in the * current picture */ public void copyKatieMidway() { String sourceFile = FileChooser.getMediaPath("KatieFancy.jpg"); Picture sourcePicture = new Picture(sourceFile); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX=100; sourceX < sourcePicture.getWidth(); sourceX++, targetX++) { // loop through the rows for (int sourceY = 0, targetY =100; sourceY < sourcePicture.getHeight(); sourceY++, targetY++) { // set the target pixel color to the source pixel color sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy just Katie's face to the current picture */ public void copyKatiesFace() { String sourceFile = FileChooser.getMediaPath("KatieFancy.jpg"); Picture sourcePicture = new Picture(sourceFile); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 70, targetX = 100; sourceX < 135; sourceX++, targetX++) { // loop through the rows for (int sourceY = 3, targetY = 100; sourceY < 80; sourceY++, targetY++) { // set the target pixel color to the source pixel color sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy flower pictures to create a collage. * All the flower pictures will be lined up near the * top of the current picture */ public void copyFlowersTop() { // create the flower pictures Picture flower1Picture = new Picture(FileChooser.getMediaPath("flower1.jpg")); Picture flower2Picture = new Picture(FileChooser.getMediaPath("flower2.jpg")); // declare the source and target pixel variables Pixel sourcePixel = null; Pixel targetPixel = null; // copy the first flower picture to the top left corner for (int sourceX = 0, targetX = 0; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = 0; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // copy the flower2 picture starting with x = 100 for (int sourceX = 0, targetX = 100; sourceX < flower2Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = 0; sourceY < flower2Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower2Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // copy the flower1 negated to x = 200 flower1Picture.negate(); for (int sourceX = 0, targetX = 200; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = 0; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // clear the blue in flower 2 picture and add at x=300 flower2Picture.clearBlue(); for (int sourceX = 0, targetX = 300; sourceX < flower2Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = 0; sourceY < flower2Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower2Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } String fileName = FileChooser.getMediaPath("7inx95in.jpg");// copy the negated flower 1 to x=400 for (int sourceX = 0, targetX = 400; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = 0; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method that will copy all of the passed source picture into * the current picture object starting with the left corner * given by xStart. It will put the sourcePicture at 5 pixels * from the bottom of this picture * @param sourcePicture the picture object to copy * @param xStart the x position to start the copy in the target */ public void copyPicture(Picture sourcePicture, int xStart) { Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX = xStart; sourceX < sourcePicture.getWidth(); sourceX++, targetX++) { // loop through the rows for (int sourceY =0, targetY = 0; sourceY < sourcePicture.getHeight(); sourceY++, targetY++) { sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy two flowers in a pattern to the * top of the current picture */ public void copyFlowersBetter() { // create the flower pictures Picture flower1Picture = new Picture(FileChooser.getMediaPath("flower1.jpg")); Picture flower2Picture = new Picture(FileChooser.getMediaPath("flower2.jpg")); // copy the first flower picture this.copyPicture (flower1Picture,0); // copy the flower2 picture starting with x = 100 this.copyPicture (flower2Picture,100); // copy the flower1 negated to x = 200 in the canvas flower1Picture.negate() ; this.copyPicture(flower1Picture,200); /* clear the blue in flower 2 picture and * add at x=300 in the canvas */ flower2Picture.clearBlue(); this.copyPicture(flower2Picture,300); // copy the negated flower 1 to x=400 this.copyPicture(flower1Picture,400); } /** * Method to copy flower pictures to create a collage. * All the flower pictures will be lined up near the * bottom of the current picture (5 pixels from the bottom) */ public void copyFlowers() { // create the flower pictures Picture flower1Picture = new Picture(FileChooser.getMediaPath("flower1.jpg")); Picture flower2Picture = new Picture(FileChooser.getMediaPath("flower2.jpg")); // declare the source and target pixel variables Pixel sourcePixel = null; Pixel targetPixel = null; // save the heights of the two pictures int flower1Height = flower1Picture.getHeight(); int flower2Height = flower2Picture.getHeight(); /* copy the first flower picture to 5 pixels from the bottom * left corner of the current picture */ for (int sourceX = 0, targetX = 0; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = this.getHeight() - flower1Height - 5; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // copy the flower2 picture starting with x = 100 for (int sourceX = 0, targetX = 100; sourceX < flower2Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = this.getHeight() - flower2Height - 5; sourceY < flower2Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower2Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // copy the flower1 negated to x = 200 flower1Picture.negate(); for (int sourceX = 0, targetX = 200; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = this.getHeight() - flower1Height - 5; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // clear the blue in flower 2 picture and add at x=300 flower2Picture.clearBlue(); for (int sourceX = 0, targetX = 300; sourceX < flower2Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = this.getHeight() - flower2Height - 5; sourceY < flower2Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower2Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } // copy the negated flower 1 to x=400 for (int sourceX = 0, targetX = 400; sourceX < flower1Picture.getWidth(); sourceX++, targetX++) { for (int sourceY = 0, targetY = this.getHeight() - flower1Height - 5; sourceY < flower1Picture.getHeight(); sourceY++, targetY++) { sourcePixel = flower1Picture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method that will copy all of the passed source picture into * the current picture object starting with the left corner * given by xStart. It will put the sourcePicture at 5 pixels * from the bottom of this picture * @param sourcePicture the picture object to copy * @param xStart the x position to start the copy in the target */ public void copyPictureTo(Picture sourcePicture, int xStart) { Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX = xStart; sourceX < sourcePicture.getWidth(); sourceX++, targetX++) { // loop through the rows for (int sourceY = 0, targetY = this.getHeight() - sourcePicture.getHeight() - 5; sourceY < sourcePicture.getHeight(); sourceY++, targetY++) { sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to create a flower collage */ public void createCollage() { // create the flower pictures Picture flower1Picture = new Picture(FileChooser.getMediaPath("flower1.jpg")); Picture flower2Picture = new Picture(FileChooser.getMediaPath("flower2.jpg")); int end1X = flower1Picture.getWidth(); int end2X = flower2Picture.getWidth(); int end1Y = flower1Picture.getHeight(); int end2Y = flower2Picture.getHeight(); // copy the first flower picture to the // top left corner of the canvas this.copy(flower1Picture,0,0,end1X,end1Y, 0,0); /* copy the flower2 picture starting with * x = 100 in the canvas */ this.copy(flower2Picture,0,0,end2X,end2Y, 100,0); // copy the flower1 negated to x = 200 in the canvas flower1Picture.negate(); this.copy(flower1Picture,0,0,end1X,end1Y, 200,0); /* clear the blue in flower 2 picture and * add at x=300 in the canvas */ flower2Picture.clearBlue(); this.copy(flower2Picture,0,0,end2X,end2Y, 300,0); // copy the negated flower 1 to x=400 this.copy(flower1Picture,0,0,end1X,end1Y, 400,0); this.mirrorHorizontal(); } /** * Method to copy from the passed source picture to the current * picture object * The copying will start at startX, startY, and end at endX-1 * and endY-1 * The copy will be placed starting at targetStartX, * targetStartY * @param sourcePicture the source picture to copy from * @param startX the starting x value in the source picture * @param startY the starting y value in the source picture * @param endX the ending x value in the source picture * @param endY the ending y value in the source picture * @param targetStartX the starting x value in the * current picture * @param targetStartY the starting y value in the * current picture */ public void copy(Picture sourcePicture, int startX, int startY, int endX, int endY, int targetStartX, int targetStartY) { Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the x values for (int x = startX, tx = targetStartX; x < endX && x < sourcePicture.getWidth() && tx < this.getWidth(); x++, tx++) { // loop through the y values for (int y = startY, ty = targetStartY; y < endY && y < sourcePicture.getHeight() && ty < this.getHeight(); y++, ty++) { sourcePixel = sourcePicture.getPixel(x,y); targetPixel = this.getPixel(tx,ty); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy from the passed source picture to the current * picture object * The copying will start at startX, startY, and end at * endX-1 and endY-1 * The copy will be placed starting at targetStartX, * targetStartY * @param sourcePicture the source picture to copy from * @param startX the starting x value in the source picture * @param startY the starting y value in the source picture * @param endX the ending x value in the source picture * @param endY the ending y value in the source picture * @param targetStartX the starting x value in the current picture * @param targetStartY the starting y value in the current picture */ public void copyNonGreenPixels(Picture sourcePicture, int startX, int startY, int endX, int endY, int targetStartX, int targetStartY) { Pixel sourcePixel = null; Pixel targetPixel = null; double distance = 50.0; if (this.getImage() == null) System.out.println(this.getFileName()); //this.getWidth(); // loop through the x values for (int x = startX, tx = targetStartX; x < endX && x < sourcePicture.getWidth() && tx < this.getWidth(); x++, tx++) { // loop through the y values for (int y = startY, ty = targetStartY; y < endY && y < sourcePicture.getHeight() && ty < this.getHeight(); y++, ty++) { sourcePixel = sourcePicture.getPixel(x,y); targetPixel = this.getPixel(tx,ty); if (sourcePixel.getGreen() < sourcePixel.getRed() + sourcePixel.getBlue()) targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method that will copy all of the passed source picture into * the current picture object starting with the left corner * given by xStart, yStart * @param sourcePicture the picture object to copy * @param xStart the x position to start the copy into on * the target * @param yStart the y position to start the copy into on * the target */ public void copyPictureTo(Picture sourcePicture, int xStart, int yStart) { Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX = xStart; sourceX < sourcePicture.getWidth(); sourceX++, targetX++) { // loop through the rows for (int sourceY = 0, targetY = yStart; sourceY < sourcePicture.getHeight(); sourceY++, targetY++) { sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy the picture of Katie but rotate * her left 90 degrees on the current picture */ public void copyKatieLeftRotation() { String sourceFile = FileChooser.getMediaPath("KatieFancy.jpg"); Picture sourcePicture = new Picture(sourceFile); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0; sourceX < sourcePicture.getWidth(); sourceX++) { // loop through the rows for (int sourceY = 0; sourceY < sourcePicture.getHeight(); sourceY++) { // set the target pixel color to the source pixel color sourcePixel = sourcePicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(sourceY, sourcePicture.getWidth() - 1 - sourceX); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to copy the flower but smaller (half as big) * on to the current picture */ public void copyFlowerSmaller() { Picture flowerPicture = new Picture(FileChooser.getMediaPath("passionFlower.jpg")); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (int sourceX = 0, targetX=0; sourceX < flowerPicture.getWidth(); sourceX+=2, targetX++) { // loop through the rows for (int sourceY=0, targetY=0; sourceY < flowerPicture.getHeight(); sourceY+=2, targetY++) { sourcePixel = flowerPicture.getPixel(sourceX,sourceY); targetPixel = this.getPixel(targetX,targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to scale any picture up to 2x * @return the new picture */ public Picture scaleBy2() { Picture target = new Picture(this.getWidth() * 2, this.getHeight() * 2); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (double sourceX = 0, targetX=0; sourceX < this.getWidth(); sourceX = sourceX + 0.5, targetX++) { // loop through the rows for (double sourceY=0, targetY=0; sourceY < this.getHeight(); sourceY = sourceY + 0.5, targetY++) { sourcePixel = this.getPixel((int) sourceX,(int) sourceY); targetPixel = target.getPixel((int) targetX,(int) targetY); targetPixel.setColor(sourcePixel.getColor()); } } return target; } /** * Method to copy a flower but scaled to 2x normal size * onto the current picture */ public void copyFlowerLarger() { Picture flowerPicture = new Picture(FileChooser.getMediaPath("rose.jpg")); Pixel sourcePixel = null; Pixel targetPixel = null; // loop through the columns for (double sourceX = 0, targetX=0; sourceX < flowerPicture.getWidth(); sourceX = sourceX + 0.5, targetX++) { // loop through the rows for (double sourceY=0, targetY=0; sourceY < flowerPicture.getHeight(); sourceY = sourceY + 0.5, targetY++) { sourcePixel = flowerPicture.getPixel((int) sourceX,(int) sourceY); targetPixel = this.getPixel((int) targetX,(int) targetY); targetPixel.setColor(sourcePixel.getColor()); } } } /** * Method to turn the brown in a picture * into red */ public void turnBrownIntoRed() { Color brown = new Color(42,25,15); Pixel[] pixels = this.getPixels(); Pixel pixel = null; // loop through the pixels for (int i=0; i= 0 && xSample < this.getWidth() && ySample >= 0 && ySample < this.getHeight()) { samplePixel = this.getPixel(xSample,ySample); redValue = redValue + samplePixel.getRed(); greenValue = greenValue + samplePixel.getGreen(); blueValue = blueValue + samplePixel.getBlue(); count = count + 1; } } } // use average color of surrounding pixels Color newColor = new Color(redValue / count, greenValue / count, blueValue / count); pixel.setColor(newColor); } } } /** * Method to blur the pixels * @param numPixels the number of pixels to average in all * directions. So if the numPixels is 2 then we will average * all pixels in the rectangle defined by 2 before the current * pixel to 2 after the current pixel */ public void blurWithCopy(int numPixels) { Pixel pixel = null; Pixel samplePixel = null; int redValue = 0; int greenValue = 0; int blueValue = 0; int count = 0; Picture copyPict = new Picture(this); // loop through the pixels for (int x=0; x < this.getWidth(); x++) { for (int y=0; y < this.getHeight(); y++) { // get the current pixel pixel = this.getPixel(x,y); // reset the count and red, green, and blue values count = 0; redValue = greenValue = blueValue = 0; // loop through pixel numPixels before x to numPixels after x for (int xSample = x - numPixels; xSample <= x + numPixels; xSample++) { for (int ySample = y - numPixels; ySample <= y + numPixels; ySample++) { // check that we are in the range of acceptable pixels if (xSample >= 0 && xSample < this.getWidth() && ySample >= 0 && ySample < this.getHeight()) { samplePixel = copyPict.getPixel(xSample,ySample); redValue = redValue + samplePixel.getRed(); greenValue = greenValue + samplePixel.getGreen(); blueValue = blueValue + samplePixel.getBlue(); count = count + 1; } } } // use average color of surrounding pixels Color newColor = new Color(redValue / count, greenValue / count, blueValue / count); pixel.setColor(newColor); } } } /** * Method to do a simple edge detection by comparing the absolute * value of the difference between the color intensities (average * of the color values) between a pixel and the pixel below it. * If the absolute value of the difference between the color * intensities is less than a passed amount the top pixel color * will be set to white. Otherwise it is set to black. * @param amount if the absolute value of the differences in the * color average is less than this * set the color to white, else black */ public void edgeDetection(double amount) { Pixel topPixel = null; Pixel bottomPixel = null; double topAverage = 0.0; double bottomAverage = 0.0; int endY = this.getHeight() - 1; /* loop through y values from 0 to height - 1 * (since compare to below pixel) */ for (int y = 0; y < endY; y++) { // loop through the x values from 0 to width for (int x = 0; x < this.getWidth(); x++) { // get the top and bottom pixels topPixel = this.getPixel(x,y); bottomPixel = this.getPixel(x,y+1); // get the color averages for the two pixels topAverage = topPixel.getAverage(); bottomAverage = bottomPixel.getAverage(); /* check if the absolute value of the difference * is less than the amount */ if (Math.abs(topAverage - bottomAverage) < amount) { topPixel.setColor(Color.WHITE); // else set the color to black } else { topPixel.setColor(Color.BLACK); } } } } /** * Method to replace the background in the current picture * with the background from another picture * @param oldBackground the old background to replace * @param newBackground the new background to use */ public void swapBackground(Picture oldBackground, Picture newBackground) { Pixel currPixel = null; Pixel oldPixel = null; Pixel newPixel = null; // loop through the columns for (int x=0; x green) copy it to the background */ int combindedColor = currPixel.getRed() + currPixel.getBlue(); if (combindedColor > currPixel.getGreen() && x + xOffset < this.getWidth() && y + yOffset < this.getHeight()) { newPixel = this.getPixel(x + xOffset,y + yOffset); newPixel.setColor(currPixel.getColor()); } } } } /** * Method to do chromakey using a green background. This method * copies from the greenPict any non green pixels into the current * picture at the offset in the area defined by the green start and * end. * @param greenPict the green screen picture * @param xGreenStart the starting X for the green screen picture * @param yGreenStart the starting Y for the green screen picture * @param xGreenEnd the ending X for the green screen picture * @param yGreenEnd the ending Y for the green screen picture * @param xBackOffset the starting X for the background pict * @param yBackOffset the ending Y for the background pict */ public void chromakeyGreenPict(Picture greenPict, int xGreenStart, int yGreenStart, int xGreenEnd, int yGreenEnd, int xBackOffset, int yBackOffset) { Pixel currPixel = null; Pixel newPixel = null; // loop through the columns for (int x=xGreenStart; x green) copy it to the background */ int combindedColor = currPixel.getRed() + currPixel.getBlue(); if (combindedColor > currPixel.getGreen()) { newPixel = this.getPixel(x + xBackOffset,y + yBackOffset); newPixel.setColor(currPixel.getColor()); } } } } /** * Method to do chromakey using a blue background in * a range * @param newBg the new background image to use to replace * the blue from the current picture * @param startX the start x in the range * @param startY the start y in the range * @param endX the end x in the range * @param endY the end y in the range */ public void chromakey(Picture newBg, int startX, int startY, int endX, int endY) { Pixel currPixel = null; Pixel newPixel = null; // loop through the columns for (int x=startX; x