Advertisement
Guest User

Untitled

a guest
May 3rd, 2016
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 13.53 KB | None | 0 0
  1. import mmn12.RGBColor;
  2.  
  3. /**
  4.  * The RGBImage class represents an image made out of pixels.<br>
  5.  * The RGB image contains a two-dimensional array containing pixels of type RGBImage, defined in mmn12.<br><br>
  6.  * The class has methods to get the properties of the image, such as its width, height,
  7.  * a certain pixel or the entire pixels array.<br>
  8.  * The class also has methods to alter, transform or rotate the image such as set a certain pixel,
  9.  * invert the colors of the image, rotate the image, flip the image or shift rows or columns.<br>
  10.  * The class also has general purpose methods such as equals or toString.
  11.  *
  12.  * @author Barack Levy, 203123898
  13.  *
  14.  */
  15. public class RGBImage {
  16.     private RGBColor[][] _imagePixels;
  17.    
  18.     /**
  19.      * The constructor creates a black image instance in a given size.<br>
  20.      *
  21.      * @param rows - the height of the image to be instantiated. Assumed to be a positive value.
  22.      * @param cols - the width of the image to be instantiated. Assumed to be a positive value.
  23.      */
  24.     public RGBImage(int rows, int cols) {
  25.         _imagePixels = new RGBColor[rows][cols];
  26.        
  27.         for (int row = 0; row < rows; row++) {
  28.             for (int col = 0; col < cols; col++) {
  29.                 _imagePixels[row][col] = new RGBColor();
  30.             }
  31.         }
  32.     }
  33.    
  34.     /**
  35.      * Copy constructor - creates a new image out of an existing one.<br>
  36.      * The method assumes the other object is not null, with valid values.
  37.      *
  38.      * @param other - the image to copy.
  39.      */
  40.     public RGBImage(RGBImage other) {
  41.         this(other._imagePixels);
  42.     }
  43.    
  44.     /**
  45.      * The constructor creates an image out of a given colors array.<br>
  46.      * The method assumes the colors array isn't null, with valid values.
  47.      *
  48.      * @param pixels - the colors array
  49.      */
  50.     public RGBImage(RGBColor[][] pixels) {
  51.         _imagePixels = new RGBColor[pixels.length][pixels[0].length];
  52.        
  53.         for (int i = 0; i < pixels.length; i++) {
  54.             for (int j = 0; j < pixels[i].length; j++) {
  55.                 _imagePixels[i][j] = new RGBColor(pixels[i][j]);
  56.             }
  57.         }
  58.     }
  59.    
  60.     /**
  61.      * Gets the height of the image.
  62.      *
  63.      * @return the height of the image
  64.      */
  65.     public int getHeight() {
  66.         return _imagePixels.length;
  67.     }
  68.    
  69.     /**
  70.      * Gets the width of the image.
  71.      *
  72.      * @return the width of the image
  73.      */
  74.     public int getWidth() {
  75.         // Note that image is guaranteed to be a rectangle,
  76.         // therefore the width of the image is constant among different rows.
  77.         return _imagePixels[0].length;
  78.     }
  79.    
  80.     /**
  81.      * A private method that checks if a given position is inside an image or not.
  82.      *
  83.      * @param row - the row of the position
  84.      * @param col - the column of the position
  85.      *
  86.      * @return true if and only if the the position is inside the image
  87.      */
  88.     private boolean isValidPixelPosition(int row, int col) {
  89.         return row >= 0 && row < getHeight() && col >= 0 && col < getWidth();
  90.     }
  91.    
  92.     /**
  93.      * Gets a certain pixel.
  94.      *
  95.      * @param row - the row of the pixel to get.
  96.      * @param col - the column of the pixel to get.
  97.      *
  98.      * @return the pixel if the position of the pixel is a valid one. A black pixel otherwise.
  99.      */
  100.     public RGBColor getPixel(int row, int col) {
  101.         // If the position of the pixel isn't valid...
  102.         if (!isValidPixelPosition(row, col)) {
  103.             // Return a black color
  104.             return new RGBColor();
  105.         }
  106.        
  107.         // Otherwise, return a copy of the pixel.
  108.         return new RGBColor(_imagePixels[row][col]);
  109.     }
  110.    
  111.     /**
  112.      * Sets a certain pixel to a given pixel.
  113.      *
  114.      * @param row - the row of the pixel to set.
  115.      * @param col - the column of the pixel to set.
  116.      * @param pixel - the new pixel color
  117.      */
  118.     public void setPixel(int row, int col, RGBColor pixel) {
  119.         // Only set the pixel if the position is a valid one and if the pixel is not null
  120.         if (pixel != null && isValidPixelPosition(row, col)) {
  121.             _imagePixels[row][col] = new RGBColor(pixel);
  122.         }
  123.     }
  124.    
  125.     /**
  126.      * Compares this image to the specified image. The result is true if and only if
  127.      * the pixels array of this image is equivalent to the given image's pixels array.
  128.      *
  129.      * @param other - the image to compare this image against
  130.      * @return true if the given image represents an image equivalent to this image, false otherwise
  131.      */
  132.     public boolean equals(RGBImage other) {
  133.         // If the other object is null, we'll return false
  134.         if (other == null) {
  135.             return false;
  136.         }
  137.        
  138.         // If the size of each image is different, then clearly they're different.
  139.         if (getWidth() != other.getWidth() || getHeight() != other.getHeight()) {
  140.             return false;
  141.         }
  142.        
  143.         // Go through each pixel
  144.         for (int row = 0; row < getHeight(); row++) {
  145.             for (int col = 0; col < getWidth(); col++) {
  146.                 // Check if one of the pixels in this image is different than the pixel in the other image
  147.                 if (!getPixel(row, col).equals(other.getPixel(row, col))) {
  148.                     return false;
  149.                 }
  150.             }
  151.         }
  152.        
  153.         return true;
  154.     }
  155.    
  156.     /**
  157.      * The method flips the image horizontally.
  158.      */
  159.     public void flipHorizontal() {
  160.         // Go through half of the columns and swap them with columns from the end, respectively.
  161.         for (int row = 0; row < getHeight(); row++) {
  162.             for (int col = 0; col <= getWidth() / 2; col++) {
  163.                 RGBColor temp = _imagePixels[row][col];
  164.                 _imagePixels[row][col] = _imagePixels[row][getWidth() - 1 - col];
  165.                 _imagePixels[row][getWidth() - 1 - col] = temp;
  166.             }
  167.         }
  168.     }
  169.    
  170.     /**
  171.      * The method flips the image vertically.
  172.      */
  173.     public void flipVertical() {
  174.         // Go through half of the rows and swap them with rows from the end, respectively.
  175.         for (int row = 0; row <= getHeight() / 2; row++) {
  176.             for (int col = 0; col < getWidth(); col++) {
  177.                 RGBColor temp = _imagePixels[row][col];
  178.                 _imagePixels[row][col] = _imagePixels[getHeight() - 1 - row][col];
  179.                 _imagePixels[getHeight() - 1 - row][col] = temp;
  180.             }
  181.         }
  182.     }
  183.    
  184.     /**
  185.      * The method inverts the colors of each of the pixels in image.
  186.      */
  187.     public void invertColors() {
  188.         for (int row = 0; row < getHeight(); row++) {
  189.             for (int col = 0; col < getWidth(); col++) {
  190.                 _imagePixels[row][col].invert();
  191.             }
  192.         }
  193.     }
  194.    
  195.     /**
  196.      * The method rotates the image clockwise.
  197.      */
  198.     public void rotateClockwise() {
  199.         // The height of the new image is set to the width of the former one.
  200.         // The width of the new image is set to the height of the former one.
  201.         RGBColor[][] newImage = new RGBColor[getWidth()][getHeight()];
  202.        
  203.         for (int row = getHeight() - 1; row >= 0; row--) {
  204.             for (int col = 0; col < getWidth(); col++) {
  205.                 // Some fancy math to rotate an image
  206.                 newImage[col][getHeight() - 1 - row] = _imagePixels[row][col];
  207.             }
  208.         }
  209.        
  210.         // Set the pixels array of this image to the new one
  211.         _imagePixels = newImage;
  212.     }
  213.    
  214.     /**
  215.      * The method rotates the image counter-clockwise.
  216.      */
  217.     public void rotateCounterClockwise() {
  218.         // The height of the new image is set to the width of the former one.
  219.         // The width of the new image is set to the height of the former one.
  220.         RGBColor[][] newImage = new RGBColor[getWidth()][getHeight()];
  221.        
  222.         for (int col = getWidth() - 1; col >= 0; col--) {
  223.             for (int row = 0; row < getHeight(); row++) {
  224.                 // Some fancy math to rotate an image
  225.                 newImage[getWidth() - 1 - col][row] = _imagePixels[row][col];
  226.             }
  227.         }
  228.        
  229.         // Set the pixels array of this image to the new one
  230.         _imagePixels = newImage;
  231.     }
  232.    
  233.     /**
  234.      * A private method that swaps one pixel with another
  235.      *
  236.      * @param row1 - the row of the first pixel
  237.      * @param col1 - the column of the first pixel
  238.      * @param row2 - the row of the second pixel
  239.      * @param col2 - the column of the second pixel
  240.      */
  241.     private void swapPixel(int row1, int col1, int row2, int col2) {
  242.         RGBColor temp = _imagePixels[row1][col1];
  243.         _imagePixels[row1][col1] = _imagePixels[row2][col2];
  244.         _imagePixels[row2][col2] = temp;
  245.     }
  246.    
  247.     /**
  248.      * A private method that swaps one column with another
  249.      *
  250.      * @param col1 - the index of the first column
  251.      * @param col2 - the index of the second column
  252.      */
  253.     private void swapColumns(int col1, int col2) {
  254.         for (int row = 0; row < getHeight(); row++) {
  255.             swapPixel(row, col1, row, col2);
  256.         }
  257.     }
  258.    
  259.     /**
  260.      * A private method that swaps one row with another
  261.      *
  262.      * @param row1 - the index of the first row
  263.      * @param row2 - the index of the second row
  264.      */
  265.     private void swapRows(int row1, int row2) {
  266.         for (int col = 0; col < getWidth(); col++) {
  267.             swapPixel(row1, col, row2, col);
  268.         }
  269.     }
  270.    
  271.     /**
  272.      * The method shifts the columns of this image some pixels in a given direction.
  273.      *
  274.      * @param offset - the number of pixels to move the image.<br>
  275.      * If the offset is positive, the image will be shifted to the right.<br>
  276.      * If the offset is negative, the image will be shifted to the left.<br>
  277.      * If the offset is zero, the method will do nothing.
  278.      */
  279.     public void shiftCol(int offset) {
  280.         // If the offset is greater than the width, the method will do nothing
  281.         // Note that the offset can also be negative, therefore we'll take the absolute value of the offset
  282.         if (offset == 0 || Math.abs(offset) > getWidth()) {
  283.             return;
  284.         }
  285.        
  286.         // If the offset is positive, we'll move everything to the right
  287.         if (offset > 0) {
  288.             // Swap each column with the column to its left by [offset] 'steps'
  289.             for (int col = getWidth() - 1; col >= offset; col--) {
  290.                 swapColumns(col, col - offset);
  291.             }
  292.            
  293.             // Change the [offset] left-most columns to black
  294.             for (int col = offset - 1; col >= 0; col--) {
  295.                 for (int row = 0; row < getHeight(); row++) {
  296.                     _imagePixels[row][col] = new RGBColor();
  297.                 }
  298.             }
  299.         }
  300.         else {
  301.             // Swap each column with the column to its right by [-offset] 'steps' (offset < 0)
  302.             for (int i = 0; i < getWidth() + offset; i++) {
  303.                 swapColumns(i, i - offset);
  304.             }
  305.            
  306.             // Change the [offset] right-most columns to black
  307.             for (int col = getWidth() + offset; col < getWidth(); col++) {
  308.                 for (int row = 0; row < getHeight(); row++) {
  309.                     _imagePixels[row][col] = new RGBColor();
  310.                 }
  311.             }
  312.         }
  313.     }
  314.    
  315.     /**
  316.      * The method shifts the rows of this image some pixels in a given direction.
  317.      *
  318.      * @param offset - the number of pixels to move the image.<br>
  319.      * If the offset is positive, the image will be shifted to the top.<br>
  320.      * If the offset is negative, the image will be shifted to the bottom.<br>
  321.      * If the offset is zero, the method will do nothing.
  322.      */
  323.     public void shiftRow(int offset) {
  324.         // If the offset is greater than the height, the method will do nothing
  325.         // Note that the offset can also be negative, therefore we'll take the absolute value of the offset
  326.         if (Math.abs(offset) > getHeight()) {
  327.             return;
  328.         }
  329.        
  330.         // If the offset is positive, we'll move everything down
  331.         if (offset > 0) {
  332.             // Swap each row with the row above it by [offset] 'steps'
  333.             for (int row = getHeight() - 1; row >= offset; row--) {
  334.                 swapRows(row, row - offset);
  335.             }
  336.            
  337.             // Change the [offset] bottom columns to black
  338.             for (int row = offset - 1; row >= 0; row--) {
  339.                 for (int col = 0; col < getWidth(); col++) {
  340.                     _imagePixels[row][col] = new RGBColor();
  341.                 }
  342.             }
  343.         }
  344.         else {
  345.             // Swap each row with the row below it by [offset] 'steps'
  346.             for (int row = 0; row < getHeight() + offset; row++) {
  347.                 swapRows(row, row - offset);
  348.             }
  349.            
  350.             // Change the [offset] top columns to black
  351.             for (int row = getHeight() + offset; row < getHeight(); row++) {
  352.                 for (int col = 0; col < getWidth(); col++) {
  353.                     _imagePixels[row][col] = new RGBColor();
  354.                 }
  355.             }
  356.         }
  357.     }
  358.    
  359.     /**
  360.      * Converts this image to a grayscale array representing the grayscale values of each pixel in this image
  361.      *
  362.      * @return a two-dimensional array representing the grayscale values of each pixels in this image
  363.      */
  364.     public double[][] toGrayscaleArray() {
  365.         double[][] grayscaleArray = new double[getHeight()][getWidth()];
  366.        
  367.         // Go through all of the pixels and calculate their grayscale values
  368.         for (int row = 0; row < grayscaleArray.length; row++) {
  369.             for (int col = 0; col < grayscaleArray[row].length; col++) {
  370.                 grayscaleArray[row][col] = _imagePixels[row][col].convertToGrayscale();
  371.             }
  372.         }
  373.        
  374.         return grayscaleArray;
  375.     }
  376.    
  377.     /**
  378.      * Returns a string representation of the object in the following format:<br>
  379.      *<pre> p11 p12 ... p1h<br>
  380.      * p21 p22 ... p2h<br>
  381.      * .   .   .   .<br>
  382.      * .   .    .  .<br>
  383.      * .   .     . .<br>
  384.      * pw1 pw2 ... pwh<br></pre>
  385.      *
  386.      * where h and w are the height and width of this image, respectively,
  387.      * and each p[i,j] is the pixel in the i'th row and j'th column.<br>
  388.      * Each pixel is displayed in the following format: (red,green,blue)
  389.      *
  390.      * @return the string representation of the object.
  391.      */
  392.     @Override
  393.     public String toString() {
  394.         StringBuilder builder = new StringBuilder();
  395.        
  396.         // Go through each pixel and add its string representation to the builder
  397.         for (int row = 0; row < getHeight(); row++) {
  398.             for (int col = 0; col < getWidth(); col++) {
  399.                 // If we're not in the last pixels of the line, add a space
  400.                 if (col != getWidth() - 1) {
  401.                     builder.append(_imagePixels[row][col] + " ");
  402.                 }
  403.                 else {
  404.                     builder.append(_imagePixels[row][col]);
  405.                 }
  406.             }
  407.            
  408.             // Add a new line after each row
  409.             builder.append('\n');
  410.         }
  411.        
  412.         return builder.toString();
  413.     }
  414.    
  415.     /**
  416.      * Clones the pixels array
  417.      *
  418.      * @return the cloned pixels array
  419.      */
  420.     public RGBColor[][] toRGBColorArray() {
  421.         RGBColor[][] copy = new RGBColor[getHeight()][getWidth()];
  422.        
  423.         // Go through each of the pixels, and create a copy of each one using the copy constructor
  424.         for (int row = 0; row < getHeight(); row++) {
  425.             for (int col = 0; col < getWidth(); col++) {
  426.                 copy[row][col] = new RGBColor(_imagePixels[row][col]);
  427.             }
  428.         }
  429.        
  430.         return copy;
  431.     }
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement