Converting Between RGB and HSV Color Spaces in JavaScript

The JavaScript code included below implements an interface to allow the user to convert between colors in the RGB (red, green, blue) color space and the HSV (hue, saturation, value) color space. To see it in action, copy it into an .html file and open that file in a web browser that runs JavaScript.

ColorSpaceConverter

<html>
<body>

<table>
	<tr>
		<td>
			<table>
				<tr>
					<td><p>Red</p></td>
					<td><input id="inputRed" type="number" value="0.0" /></td>
				</tr>
				<tr>
					<td><p>Green</p></td>
					<td><input id="inputGreen" type="number" value="0.5" /></td>
				</tr>
				<tr>
					<td><p>Blue</p></td>
					<td><input id="inputBlue" type="number" value="1.0" /></td>
				</tr>
				<tr>
					<td colspan="2"><button id="buttonConvertRGB">Convert from RGB&gt;</button></td>
				</tr>
			</table>
		</td>

		<td>
			<div id="divColorSwatch" style="border:1px solid;width:100px;height:100px" />
		</td>

		<td>
			<table>
				<tr>
					<td><p>Hue</p></td>
					<td><input id="inputHue" type="number" value="0.5" /></td>
				</tr>
				<tr>
					<td><p>Saturation</p></td>
					<td><input id="inputSaturation" type="number" value="0.5" /></td>
				</tr>
				<tr>
					<td><p>Value</p></td>
					<td><input id="inputValue" type="number" value="0.5" /></td>
				</tr>
				<tr>
					<td colspan="2"><button id="buttonConvertHSV">&lt; Convert from HSV</button></td>
				</tr>
			</table>
		</td>
	</tr>
</table>

<script type='text/javascript'>

function ColorSpaceConversionTest()
{
	this.main = function()
	{
		var buttonConvertRGB = document.getElementById("buttonConvertRGB")
		buttonConvertRGB.onclick = this.buttonConvertRGB_Click;

		var buttonConvertHSV = document.getElementById("buttonConvertHSV");
		buttonConvertHSV.onclick = this.buttonConvertHSV_Click;
	}

	this.buttonConvertRGB_Click = function(event)
	{
		var inputRed = document.getElementById("inputRed");
		var inputGreen = document.getElementById("inputGreen");
		var inputBlue = document.getElementById("inputBlue");

		var inputHue = document.getElementById("inputHue");
		var inputSaturation = document.getElementById("inputSaturation");
		var inputValue = document.getElementById("inputValue");

		var divColorSwatch = document.getElementById("divColorSwatch");

		var colorRGB = new ColorRGB
		(
			parseFloat(inputRed.value),
			parseFloat(inputGreen.value),
			parseFloat(inputBlue.value)
		);

		var colorHSV = ColorSpaceConverter.convertColorRGBToHSV
		(
			colorRGB	
		);

		inputHue.value = colorHSV.hue;
		inputSaturation.value = colorHSV.saturation;
		inputValue.value = colorHSV.value;

		divColorSwatch.style.backgroundColor = 
			"rgba("  
				+ Math.floor(colorRGB.red * ColorRGB._255) + "," 
				+ Math.floor(colorRGB.green  * ColorRGB._255) + ","
				+ Math.floor(colorRGB.blue  * ColorRGB._255) + ","
				+ 1
			+ ")";
	}

	this.buttonConvertHSV_Click = function(event)
	{
		var inputRed = document.getElementById("inputRed");
		var inputGreen = document.getElementById("inputGreen");
		var inputBlue = document.getElementById("inputBlue");

		var inputHue = document.getElementById("inputHue");
		var inputSaturation = document.getElementById("inputSaturation");
		var inputValue = document.getElementById("inputValue");

		var divColorSwatch = document.getElementById("divColorSwatch");

		var colorHSV = new ColorHSV
		(
			parseFloat(inputHue.value),
			parseFloat(inputSaturation.value),
			parseFloat(inputValue.value)
		);

		var colorRGB = ColorSpaceConverter.convertColorHSVToRGB
		(
			colorHSV
		);

		inputRed.value = colorRGB.red;
		inputGreen.value = colorRGB.green;
		inputBlue.value = colorRGB.blue;

		divColorSwatch.style.backgroundColor = 
			"rgba("  
				+ Math.floor(colorRGB.red * ColorRGB._255) + "," 
				+ Math.floor(colorRGB.green  * ColorRGB._255) + ","
				+ Math.floor(colorRGB.blue  * ColorRGB._255) + ","
				+ 1
			+ ")";
	}
}

// classes

function ColorRGB(red, green, blue)
{
	this.red = red;
	this.green = green;
	this.blue = blue;
}
{
	ColorRGB._255 = 255;
}

function ColorHSV(hue, saturation, value)
{
	this.hue = hue;
	this.saturation = saturation;
	this.value = value;
}

function ColorSpaceConverter()
{
	// do nothing
}
{
	ColorSpaceConverter.convertColorRGBToHSV = function(colorRGB)
	{
		var returnValue = null;

		var red = colorRGB.red;
		var green = colorRGB.green;
		var blue = colorRGB.blue;

		var hue = null;
		var saturation = null;
		var value = null;

		var rgbComponentMin = red;

		if (rgbComponentMin > green)
		{
			rgbComponentMin = green;
		}

		if (rgbComponentMin > blue)
		{
			rgbComponentMin = blue;
		}

		var rgbComponentMax = red;

		if (rgbComponentMax < green)
		{
			rgbComponentMax = green;
		}

		if (rgbComponentMax < blue)
		{
			rgbComponentMax = blue;
		}

		var rgbComponentRange = rgbComponentMax - rgbComponentMin;

		value = rgbComponentMax;

		if (rgbComponentRange == 0)
		{
			hue = 0;
		   	saturation = 0;
		}
		else
		{
			if (rgbComponentMax == red)
			{
				hue = (green - blue) / rgbComponentRange;
			}
			else if (rgbComponentMax == green)
			{
				hue = (blue - red) / rgbComponentRange + 2;
			}
			else if (rgbComponentMax == blue)
			{
				hue = (red - green) / rgbComponentRange + 4;
			}

			saturation = rgbComponentRange / value;
		}

		hue = hue / 6;

		returnValue = new ColorHSV(hue, saturation, value);

		return returnValue;
	}

	ColorSpaceConverter.convertColorHSVToRGB = function(colorHSV)
	{
		var hue = colorHSV.hue;
		var saturation = colorHSV.saturation;
		var value = colorHSV.value;

		var chroma = value * saturation;

		if (saturation == 0)
		{
			returnValue = new ColorRGB(value, value, value);
		}
		else
		{
			var hueTimesSix = hue * 6;

			var quantity = chroma * (1 - Math.abs(hueTimesSix % 2 - 1));

			if (hueTimesSix < 1) 
			{ 
				returnValue = new ColorRGB
				(
					chroma,
					quantity,
					0
				);
			}
			else if (hueTimesSix < 2) 
			{ 
				returnValue = new ColorRGB
				(
					quantity,
					chroma,
					0
				);
			}
			else if (hueTimesSix < 3) 
			{ 
				returnValue = new ColorRGB
				(
					0,
					chroma,
					quantity
				);
			}
			else if (hueTimesSix < 4) 
			{ 
				returnValue = new ColorRGB
				(
					0, 
					quantity, 
					chroma
				);
			}
			else if (hueTimesSix < 5) 
			{ 
				returnValue = new ColorRGB
				(
					quantity, 
					0, 
					chroma
				);
			}
			else // if (hueTimesSix <= 6)  
			{
				returnValue = new ColorRGB
				(
					chroma, 
					0,
					quantity
				);
			}
		}

		return returnValue;
	}
}

// run

new ColorSpaceConversionTest().main();

</script>
</body>
</html>
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s