Implementation of color util

This commit is contained in:
Ziver Koc 2023-05-06 01:11:46 +02:00
parent 670f95689d
commit 676ce6a33f
2 changed files with 178 additions and 0 deletions

114
src/zutil/ColorUtil.java Normal file
View file

@ -0,0 +1,114 @@
package zutil;
import zutil.converter.Converter;
/**
* A utility class for color calculations and functions.
*/
public class ColorUtil {
/**
* Generates a Hex String in the format '#RRGGBB'
*
* @param red the red color value between 0-255
* @param green the green color value between 0-255
* @param blue the blue color value between 0-255
* @return a String hex
*/
public static String getHexString(int red, int green, int blue) {
byte redByte = Converter.toByte(red);
byte greenByte = Converter.toByte(green);
byte blueByte = Converter.toByte(blue);
return "#" + Converter.toHexString(new byte[]{redByte, greenByte, blueByte});
}
/**
* Converts a hex string with the format '#RRGGBB' to a int array of length 3 containing the red, green, blue integer values.
*
* @param hex a String hex.
* @return a int array representing RGB.
*/
public static int[] getRgbFromHexString(String hex) {
if (hex.length() != 7)
throw new IllegalArgumentException("Color hex length is not 7 but was " + hex.length());
else if (hex.charAt(0) != '#')
throw new IllegalArgumentException("Color hex is required to start with the char #");
byte[] rgbByte = Converter.hexToByte(hex.substring(1));
return new int[]{
Converter.toInt(rgbByte[0]),
Converter.toInt(rgbByte[1]),
Converter.toInt(rgbByte[2])};
}
/**
* Calculates a hue value based on RGB values.
*
* @param red the red color value between 0-255
* @param green the green color value between 0-255
* @param blue the blue color value between 0-255
* @return a hue grade in the range of 0-360 degrees.
*/
public static double getHue(int red, int green, int blue) {
double red_percent = red / 255.0;
double green_percent = green / 255.0;
double blue_percent = blue / 255.0;
double cMax = Math.max(red_percent, Math.max(green_percent, blue_percent));
double cMin = Math.min(red_percent, Math.min(green_percent, blue_percent));
double delta = cMax - cMin;
if (delta == 0)
return 0;
else if (cMax == red_percent)
return 60 * (((green_percent - blue_percent) / delta) % 6);
else if (cMax == green_percent)
return 60 * (((blue_percent - red_percent) / delta) + 2);
else if (cMax == blue_percent)
return 60 * (((red_percent - green_percent) / delta) + 4);
throw new IllegalStateException();
}
/**
* Calculates a saturation percentage based on RGB values.
*
* @param red the red color value between 0-255
* @param green the green color value between 0-255
* @param blue the blue color value between 0-255
* @return a percentage of saturation in the range of 0.0 to 1.0.
*/
public static double getSaturation(int red, int green, int blue) {
double red_percent = red / 255.0;
double green_percent = green / 255.0;
double blue_percent = blue / 255.0;
double cMax = Math.max(red_percent, Math.max(green_percent, blue_percent));
double cMin = Math.min(red_percent, Math.min(green_percent, blue_percent));
double delta = cMax - cMin;
if (delta == 0)
return 0;
else
return delta / (1 - Math.abs(2 * getLightness(red, green, blue) - 1));
}
/**
* Calculates a lightness percentage based on RGB values.
*
* @param red the red color value between 0-255
* @param green the green color value between 0-255
* @param blue the blue color value between 0-255
* @return a percentage of lightness in the range of 0.0 to 1.0.
*/
public static double getLightness(int red, int green, int blue) {
double red_percent = red / 255.0;
double green_percent = green / 255.0;
double blue_percent = blue / 255.0;
double cMax = Math.max(red_percent, Math.max(green_percent, blue_percent));
double cMin = Math.min(red_percent, Math.min(green_percent, blue_percent));
return (cMax + cMin) / 2.0;
}
}

View file

@ -0,0 +1,64 @@
package zutil;
import org.junit.Test;
import static org.junit.Assert.*;
public class ColorUtilTest {
@Test
public void getHexString() {
assertEquals("#000000", ColorUtil.getHexString(0, 0, 0));
assertEquals("#090909", ColorUtil.getHexString(9, 9, 9));
assertEquals("#ffffff", ColorUtil.getHexString(255, 255, 255));
assertEquals("#6496c8", ColorUtil.getHexString(100, 150, 200));
}
@Test
public void getRgbFromHexString() {
assertArrayEquals(new int[]{0, 0, 0}, ColorUtil.getRgbFromHexString("#000000"));
assertArrayEquals(new int[]{9, 9, 9}, ColorUtil.getRgbFromHexString("#090909"));
assertArrayEquals(new int[]{255, 255, 255}, ColorUtil.getRgbFromHexString("#ffffff"));
assertArrayEquals(new int[]{100, 150, 200}, ColorUtil.getRgbFromHexString("#6496c8"));
}
@Test
public void getHueFromRGB() {
assertEquals(0.0, ColorUtil.getHue(0, 0, 0), 0);
assertEquals(0.0, ColorUtil.getHue(255, 255, 255), 0);
assertEquals(0.0, ColorUtil.getHue(255, 0, 0), 0);
assertEquals(120.0, ColorUtil.getHue(0, 255, 0), 0);
assertEquals(240.0, ColorUtil.getHue(0, 0, 255), 0);
assertEquals(0.0, ColorUtil.getHue(128, 128, 128), 0);
assertEquals(12.0, ColorUtil.getHue(100, 60, 50), 0);
assertEquals(108.0, ColorUtil.getHue(60, 100, 50), 0);
assertEquals(228.0, ColorUtil.getHue(50, 60, 100), 0);
}
@Test
public void getSaturationFromRGB() {
assertEquals(0.0, ColorUtil.getSaturation(0, 0, 0), 0);
assertEquals(0.0, ColorUtil.getSaturation(255, 255, 255), 0);
assertEquals(1.0, ColorUtil.getSaturation(255, 0, 0), 0);
assertEquals(1.0, ColorUtil.getSaturation(0, 255, 0), 0);
assertEquals(1.0, ColorUtil.getSaturation(0, 0, 255), 0);
assertEquals(0.0, ColorUtil.getSaturation(128, 128, 128), 0);
assertEquals(0.333, ColorUtil.getSaturation(100, 60, 50), 0.001);
assertEquals(0.333, ColorUtil.getSaturation(60, 100, 50), 0.001);
assertEquals(0.333, ColorUtil.getSaturation(50, 60, 100), 0.001);
}
@Test
public void getLightnessFromRGB() {
assertEquals(0.0, ColorUtil.getLightness(0, 0, 0), 0);
assertEquals(1.0, ColorUtil.getLightness(255, 255, 255), 0);
assertEquals(0.5, ColorUtil.getLightness(255, 0, 0), 0);
assertEquals(0.5, ColorUtil.getLightness(0, 255, 0), 0);
assertEquals(0.5, ColorUtil.getLightness(0, 0, 255), 0);
assertEquals(0.75, ColorUtil.getLightness(191, 191, 191), 0.01);
assertEquals(0.5, ColorUtil.getLightness(128, 128, 128), 0.01);
assertEquals(0.294, ColorUtil.getLightness(100, 60, 50), 0.01);
assertEquals(0.294, ColorUtil.getLightness(60, 100, 50), 0.01);
assertEquals(0.294, ColorUtil.getLightness(50, 60, 100), 0.01);
}
}