package eecs2030.test1; import java.awt.Color; /** * A class that represents gray values for grayscale (black-and-white) * images. A gray value can be an integer value between 0 and 255, * or a double value between 0.0 and 1.0. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
gray value as double   gray value as int
0.00
1.0 / 255.01
2.0 / 255.02
3.0 / 255.03
......
254.0 / 255.0254
1.0255
* *

* A Gray instance can be created using any double value * between 0.0 and 1.0; it is not required that there be an exact * match between the double gray value and an int gray value. * See {@link #toInt} for details on how a double gray value is * converted to an int gray value. * */ public final class Gray implements Comparable { final private double gray; final private boolean isInt; /** * The minimum double gray value. */ public final static double MIN_DOUBLE_VALUE = 0.0; /** * The maximum double gray value. */ public final static double MAX_DOUBLE_VALUE = 1.0; /** * The minimum int gray value. */ public final static int MIN_INT_VALUE = 0; /** * The maximum int gray value. */ public final static int MAX_INT_VALUE = 255; /** * Initializes the gray value of this object to g. * The value returned by asDouble() will be equal to * g: * *

     * double g = 0.12345;
     * Gray gray = new Gray(g);
     * double value = gray.asDouble();   // value is equal to g
     * 
* * @param g a gray value * @pre. g between 0.0 and 1.0, inclusive * @throws IllegalArgumentException if g is less than 0.0 or greater than 1.0 */ public Gray(double g) { if (g < 0.0 || g > 1.0) { throw new IllegalArgumentException("value must be between 0 and 1"); } this.gray = g; this.isInt = false; } /** * Initializes the gray value of this object to g. * The value returned by asInt() will be equal to * g: * *
     * int g = 128;
     * Gray gray = new Gray(g);
     * int value = gray.asInt();   // value is equal to g
     * 
* * @param g a gray value between 0 and 255 * @pre. g between 0 and 255, inclusive * @throws IllegalArgumentException if g is less than 0 or greater than 255 */ public Gray(int g) { this.gray = Gray.toDouble(g); this.isInt = true; } /** * Initializes the gray value of this object by copying another * Gray object. * * @param other a Gray object to copy */ public Gray(Gray other) { this.gray = other.gray; this.isInt = other.isInt; } /** * Returns the gray value of this object as an int. If this * gray object was created using a double value, then that * double value is converted to the equivalent int gray * value and returned (see {@link #toInt} for details). * *
     * Gray gray = new Gray(192);
     * int value = gray.asInt();    // value is equal to 192
     * 
     * gray = new Gray(1.0);
     * value = gray.asInt();        // value is equal to 255
     * 
* * @return the gray value of this object expressed as an integer */ public int asInt() { return Gray.toInt(this.gray); } /** * Returns the gray value of this object as a double. If this * gray object was created using an int value, then that * int value is converted to the equivalent double gray * value and returned (see {@link #toDouble} for details). * *
     * Gray gray = new Gray(0.5);
     * double value = gray.asDouble();    // value is equal to 0.5
     * 
     * gray = new Gray(255);
     * value = gray.asDouble();           // value is equal to 1.0
     * 
* * @return the gray value of this object expressed as a double */ public double asDouble() { return this.gray; } /** * Converts an integer gray value to its equivalent double gray value. * The equivalent double value is equal to * value / Gray.MAX_DOUBLE_VALUE * * @param value a gray value between 0 and 255 * @return the equivalent double gray value * @pre. value between 0 and 255, inclusive * @throws IllegalArgumentException if value is less than 0 or greater than 255 */ public static double toDouble(int value) { if (value < 0 || value > 255) { throw new IllegalArgumentException("value must be between 0 and 255"); } return (0.0 + value) / Gray.MAX_INT_VALUE; } /** * Converts a double gray value to its equivalent int gray value. * The equivalent int value is equal to round(Gray.MAX_DOUBLE_VALUE × value) * where round rounds the computed value to the nearest int value. * * @param value a gray value between 0.0 and 1.0 * @return the equivalent int gray value * @pre. value between 0.0 and 1.0, inclusive * @throws IllegalArgumentException if value is less than 0.0 or greater than 1.0 */ public static int toInt(double value) { if (value < 0.0 || value > 1.0) { throw new IllegalArgumentException("value must be between 0 and 1"); } return (int) Math.round(Gray.MAX_INT_VALUE * value); } /** * Creates a Gray instance from a Color. * The gray value of a color is given by * 0.299 × R + 0.587 × G + 0.114 × B * where R is the red value of the color, * G is the green value of the color, * B is the blue value of the color, and all of R, * G, and B are double values between 0.0 and 1.0. * * @param c a color * @return a Gray instance */ public static Gray fromRGB(Color c) { double red = (double) c.getRed() / Gray.MAX_INT_VALUE; double green = (double) c.getGreen() / Gray.MAX_INT_VALUE; double blue = (double) c.getBlue() / Gray.MAX_INT_VALUE; double gray = 0.299 * red + 0.587 * green + 0.114 * blue; return new Gray(gray); } /** * Returns a string representation of this Gray instance. * The string is simply the gray value of this instance. * *
     * Gray gray = new Gray(18);
     * String s = gray.toString();    // s is equal to "18"
     * 
     * gray = new Gray(0.125);
     * s = gray.toString();           // s is equal to "0.125"
     * 
* * @return a string representation of this instance */ @Override public String toString() { String s = ""; if (this.isInt) { s += this.asInt(); } else { s += this.asDouble(); } return s; } /** * Compares two Gray instances by their gray values. * The instances are compared using their gray values represented * as double values (between 0.0 and 1.0). Returns:

* -1 if this gray value is less than the other gray value,
* 1 if this gray value is greater than the other gray value, and
* 0 otherwise. * * @return -1, 1, or 0 as indicated in the description above */ @Override public int compareTo(Gray other) { int result = 0; if (this.gray < other.gray) { result = -1; } else if (this.gray > other.gray) { result = 1; } return result; } /** * Compares two Gray instances for equality. * The result is true if and only if the argument is * not null and is a Gray instance whose * gray value is equal to this instance's gray value. The gray * levels are checked for equality by converting them to int * values (between 0 and 255) and comparing the two int values. * * @return true if the int gray levels of the two instances * are equal, and false otherwise */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Gray other = (Gray) obj; if (this.asInt() != other.asInt()) return false; return true; } public static void main(String[] args) { System.out.println(new Gray(0.0)); } }