Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ColorUtil] Extend rgbToHsb(PercentType[]) for RGBW #3882

Merged
merged 2 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -286,40 +286,43 @@ public static double[] hsbToXY(HSBType hsb, Gamut gamut) {
*/
public static HSBType rgbToHsb(int[] rgbw) throws IllegalArgumentException {
if (rgbw.length == 4) {
return rgbwToHsb(rgbw);
if (!inByteRange(rgbw[0]) || !inByteRange(rgbw[1]) || !inByteRange(rgbw[2]) || !inByteRange(rgbw[3])) {
throw new IllegalArgumentException("rgbToHsb requires 3 or 4 values between 0 and 255");
}
return rgbwToHsb(new PercentType[] { convertByteToColorPercent(rgbw[0]), convertByteToColorPercent(rgbw[1]),
convertByteToColorPercent(rgbw[2]), convertByteToColorPercent(rgbw[3]) });
}
if (rgbw.length != 3 || !inByteRange(rgbw[0]) || !inByteRange(rgbw[1]) || !inByteRange(rgbw[2])) {
throw new IllegalArgumentException("RGB array only allows values between 0 and 255");
throw new IllegalArgumentException("rgbToHsb requires 3 or 4 values between 0 and 255");
}
return rgbToHsb(new PercentType[] { convertByteToColorPercent(rgbw[0]), convertByteToColorPercent(rgbw[1]),
convertByteToColorPercent(rgbw[2]) });
}

/**
* Transform <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">HSV</a> based {@link HSBType} to RGBW.
* Transform RGBW to <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">HSV</a> based {@link HSBType}.
*
* See <a href=
* "https://stackoverflow.com/questions/40312216/converting-rgb-to-rgbw">Converting RGB to RGBW</a>.
*
* This function does not round the components. For conversion to integer values in the range 0 to 255 use
* {@link #hsbToRgb(HSBType)}.
*
* See also: {@link #hsbToRgb(HSBType)}, {@link #hsbTosRgb(HSBType)}, {@link #hsbToRgbPercent(HSBType)}
*
* @param rgbw array of four int with the RGBW values in the range 0 to 255.
* @return hsb an {@link HSBType} value.
*
*/
private static HSBType rgbwToHsb(int[] rgbw) {
if (rgbw.length != 4 || !inByteRange(rgbw[0]) || !inByteRange(rgbw[1]) || !inByteRange(rgbw[2])
|| !inByteRange(rgbw[3])) {
throw new IllegalArgumentException("RGBW array only allows values between 0 and 255 with 4 values");
private static HSBType rgbwToHsb(PercentType[] rgbw) {
if (rgbw.length != 4) {
throw new IllegalArgumentException("RGBW requires 4 values");
}

BigDecimal luminance = BigDecimal.valueOf(rgbw[3]);
BigDecimal inRed = BigDecimal.valueOf(rgbw[0]).add(luminance);
BigDecimal inGreen = BigDecimal.valueOf(rgbw[1]).add(luminance);
BigDecimal inBlue = BigDecimal.valueOf(rgbw[2]).add(luminance);
BigDecimal luminance = BigDecimal.valueOf(rgbw[3].doubleValue() / PercentType.HUNDRED.doubleValue() * 255.0);
BigDecimal inRed = BigDecimal.valueOf(rgbw[0].doubleValue() / PercentType.HUNDRED.doubleValue() * 255.0)
.add(luminance);
BigDecimal inGreen = BigDecimal.valueOf(rgbw[1].doubleValue() / PercentType.HUNDRED.doubleValue() * 255.0)
.add(luminance);
BigDecimal inBlue = BigDecimal.valueOf(rgbw[2].doubleValue() / PercentType.HUNDRED.doubleValue() * 255.0)
.add(luminance);

// Get the maximum between R, G, and B
final BigDecimal maxColor = BIG_DECIMAL_255.min(inRed.max(inGreen.max(inBlue)).max(BigDecimal.ZERO));
Expand All @@ -342,11 +345,14 @@ private static HSBType rgbwToHsb(int[] rgbw) {
* Transform <a href="https://en.wikipedia.org/wiki/SRGB">sRGB</a> color format to
* <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">HSV</a> based {@link HSBType}.
*
* @param rgb array of three {@link PercentType} with the RGB values in the range 0 to 100 percent.
* @param rgb array of three or four {@link PercentType} with the RGB(W) values in the range 0 to 100 percent.
* @return the corresponding {@link HSBType}.
* @throws IllegalArgumentException when input array has wrong size or exceeds allowed value range.
*/
public static HSBType rgbToHsb(PercentType[] rgb) throws IllegalArgumentException {
if (rgb.length == 4) {
return rgbwToHsb(rgb);
}
if (rgb.length != 3) {
throw new IllegalArgumentException("RGB array needs exactly three values!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,46 @@ public void rgbwToHsbTest() {
HSBType hsb = ColorUtil.rgbToHsb(new int[] { 255, 0, 0, 0 });
int[] convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 255, 0, 0 }, convertedRgb);
hsb = ColorUtil.rgbToHsb(
new PercentType[] { new PercentType(100), new PercentType(0), new PercentType(0), new PercentType(0) });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 255, 0, 0 }, convertedRgb);

// Test Green
hsb = ColorUtil.rgbToHsb(new int[] { 0, 255, 0, 0 });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 255, 0 }, convertedRgb);
hsb = ColorUtil.rgbToHsb(
new PercentType[] { new PercentType(0), new PercentType(100), new PercentType(0), new PercentType(0) });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 255, 0 }, convertedRgb);

// Test Blue
hsb = ColorUtil.rgbToHsb(new int[] { 0, 0, 255, 0 });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 0, 255 }, convertedRgb);
hsb = ColorUtil.rgbToHsb(
new PercentType[] { new PercentType(0), new PercentType(0), new PercentType(100), new PercentType(0) });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 0, 255 }, convertedRgb);

// Test White
hsb = ColorUtil.rgbToHsb(new int[] { 0, 0, 0, 255 });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 255, 255, 255 }, convertedRgb);
hsb = ColorUtil.rgbToHsb(
new PercentType[] { new PercentType(0), new PercentType(0), new PercentType(0), new PercentType(100) });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 255, 255, 255 }, convertedRgb);

// Test Black
hsb = ColorUtil.rgbToHsb(new int[] { 0, 0, 0, 0 });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 0, 0 }, convertedRgb);
hsb = ColorUtil.rgbToHsb(
new PercentType[] { new PercentType(0), new PercentType(0), new PercentType(0), new PercentType(0) });
convertedRgb = ColorUtil.hsbToRgb(hsb);
assertRgbEquals(new int[] { 0, 0, 0 }, convertedRgb);
}

@ParameterizedTest
Expand Down