From b8b4209f950c0af700ea88c77fb3df527784238c Mon Sep 17 00:00:00 2001 From: Alex Buis Date: Tue, 1 May 2018 20:56:05 +0200 Subject: [PATCH] #130 Fix color higher than 255 - fixed coding standards in color conversion tool. - added unit test for the 0..255 range fix. --- library/Phue/Helper/ColorConversion.php | 29 ++++++++++++------- .../Phue/Test/Helper/ColorConversionTest.php | 25 ++++++++++------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/library/Phue/Helper/ColorConversion.php b/library/Phue/Helper/ColorConversion.php index 4e0dde0..e0ffc91 100644 --- a/library/Phue/Helper/ColorConversion.php +++ b/library/Phue/Helper/ColorConversion.php @@ -29,7 +29,7 @@ public static function convertRGBToXY($red, $green, $blue) $normalizedToOne['red'] = $red / 255; $normalizedToOne['green'] = $green / 255; $normalizedToOne['blue'] = $blue / 255; - + // Make colors more vivid foreach ($normalizedToOne as $key => $normalized) { if ($normalized > 0.04045) { @@ -38,12 +38,12 @@ public static function convertRGBToXY($red, $green, $blue) $color[$key] = $normalized / 12.92; } } - + // Convert to XYZ using the Wide RGB D65 formula $xyz['x'] = $color['red'] * 0.664511 + $color['green'] * 0.154324 + $color['blue'] * 0.162028; $xyz['y'] = $color['red'] * 0.283881 + $color['green'] * 0.668433 + $color['blue'] * 0.047685; $xyz['z'] = $color['red'] * 0.000000 + $color['green'] * 0.072310 + $color['blue'] * 0.986039; - + // Calculate the x/y values if (array_sum($xyz) == 0) { $x = 0; @@ -52,14 +52,14 @@ public static function convertRGBToXY($red, $green, $blue) $x = $xyz['x'] / array_sum($xyz); $y = $xyz['y'] / array_sum($xyz); } - + return array( 'x' => $x, 'y' => $y, 'bri' => round($xyz['y'] * 255) ); } - + /** * Converts XY (and brightness) values to RGB * @@ -76,12 +76,13 @@ public static function convertXYToRGB($x, $y, $bri = 255) $xyz['y'] = $bri / 255; $xyz['x'] = ($xyz['y'] / $y) * $x; $xyz['z'] = ($xyz['y'] / $y) * $z; - + // Convert to RGB using Wide RGB D65 conversion $color['red'] = $xyz['x'] * 1.656492 - $xyz['y'] * 0.354851 - $xyz['z'] * 0.255038; $color['green'] = -$xyz['x'] * 0.707196 + $xyz['y'] * 1.655397 + $xyz['z'] * 0.036152; $color['blue'] = $xyz['x'] * 0.051713 - $xyz['y'] * 0.121364 + $xyz['z'] * 1.011530; - + + $maxValue = 0; foreach ($color as $key => $normalized) { // Apply reverse gamma correction if ($normalized <= 0.0031308) { @@ -89,11 +90,19 @@ public static function convertXYToRGB($x, $y, $bri = 255) } else { $color[$key] = (1.0 + 0.055) * pow($normalized, 1.0 / 2.4) - 0.055; } - + $color[$key] = max(0, $color[$key]); + if ($maxValue < $color[$key]) { + $maxValue = $color[$key]; + } + } + foreach ($color as $key => $normalized) { + if ($maxValue > 1) { + $color[$key] /= $maxValue; + } // Scale back from a maximum of 1 to a maximum of 255 $color[$key] = round($color[$key] * 255); } - + return $color; } -} +} \ No newline at end of file diff --git a/tests/Phue/Test/Helper/ColorConversionTest.php b/tests/Phue/Test/Helper/ColorConversionTest.php index 31c1be2..5dd31a4 100644 --- a/tests/Phue/Test/Helper/ColorConversionTest.php +++ b/tests/Phue/Test/Helper/ColorConversionTest.php @@ -16,32 +16,32 @@ class ColorConversionTest extends \PHPUnit_Framework_TestCase { /** * Test: convert RGB to XY and brightness - * + * * @covers \Phue\Helper\ColorConversion::convertRGBToXY */ public function testConvertRGBToXY() { // Values from: http://www.developers.meethue.com/documentation/hue-xy-values - + // Alice Blue $xy = ColorConversion::convertRGBToXY(239, 247, 255); $this->assertEquals(0.3088, $xy['x'], '', 0.0001); $this->assertEquals(0.3212, $xy['y'], '', 0.0001); $this->assertEquals(233, $xy['bri']); - + // Firebrick $xy = ColorConversion::convertRGBToXY(178, 33, 33); $this->assertEquals(0.6622, $xy['x'], '', 0.0001); $this->assertEquals(0.3024, $xy['y'], '', 0.0001); $this->assertEquals(35, $xy['bri']); - + // Medium Sea Green $xy = ColorConversion::convertRGBToXY(61, 178, 112); $this->assertEquals(0.1979, $xy['x'], '', 0.0001); $this->assertEquals(0.5005, $xy['y'], '', 0.0001); $this->assertEquals(81, $xy['bri']); } - + /** * Test: convert XY and brightness to RGB * @@ -50,23 +50,30 @@ public function testConvertRGBToXY() public function testConvertXYToRGB() { // Conversion back from the test above - + // Alice Blue $rgb = ColorConversion::convertXYToRGB(0.3088, 0.3212, 233); $this->assertEquals($rgb['red'], 239); $this->assertEquals($rgb['green'], 247); $this->assertEquals($rgb['blue'], 255); - + // Firebrick $rgb = ColorConversion::convertXYToRGB(0.6622, 0.3024, 35); $this->assertEquals($rgb['red'], 178); $this->assertEquals($rgb['green'], 33); $this->assertEquals($rgb['blue'], 33); - + // Medium Sea Green $rgb = ColorConversion::convertXYToRGB(0.1979, 0.5005, 81); $this->assertEquals($rgb['red'], 61); $this->assertEquals($rgb['green'], 178); $this->assertEquals($rgb['blue'], 112); + + // Test to make sure single RGB values falls within 0..255 range. + // old situation this was r -18, g 186, b -613. + $rgb = ColorConversion::convertXYToRGB(0.1979, 1.5005, 81); + $this->assertEquals($rgb['red'], 0); + $this->assertEquals($rgb['green'], 186); + $this->assertEquals($rgb['blue'], 0); } -} +} \ No newline at end of file