Code review: Modifying RGB by Manipulating HSV colors

In my ongoing question for a programmatically controlled gradient function (here and here) I stumbled upon a built in python library that does conversions between RGB and HSV. This allows be manipulate the RGB colors in the manner I desire. So I wrote a function to do so. However not being the most skilled in python, I have no idea if it can be done in a better manner.

This function:

  1. Takes an RGB value in the form of #FFAABB etc
  2. Converts it to HSV
  3. Multiples the V component by a user supplied value
  4. Converts it back to RGB
  5. Reformats it back to #AABBCC format etc

Note that rgb_to_hsv returns a tuple, which of course is immutable in python.

def mulColorV(self, rgbHex, factV):
	"""
	Custom method that can be invoked directly on this component.

	Arguments:
		self: A reference to the component that is invoking this function.
		rgbHex: 
		factV: 
	"""
	try:
		import colorsys
		rgbDec=list(int(rgbHex[i:i+2], 16)/255.0 for i in (1, 3, 5))
		hsvDec=list(colorsys.rgb_to_hsv(rgbDec[0],rgbDec[1],rgbDec[2]))
		hsvDec[2]*=factV
		if hsvDec[2]>1.0:
			hsvDec[2]=1.0
		if hsvDec[2]<0.0:
			hsvDec[2]=0.0
		newRgb=colorsys.hsv_to_rgb(hsvDec[0],hsvDec[1],hsvDec[2])
		newHex='#{0:02X}{1:02X}{2:02X}'.format(int(newRgb[0]*255),int(newRgb[1]*255),int(newRgb[2]*255))
		return newHex
	except:
		return '#000000'

You may be interested in Java’s Color class, which has various static methods to convert between HSV and RGB representations:
https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Color.html#getHSBColor(float,float,float)

2 Likes

I just took a look at the java classes, and there seemed to be so much jumping through hoops that I’d end up with about the same code complexity that I already have. So unless there is a performance reason to take care of I’m currently not intending a re-write

That’s fair. I would expect better performance out of a more Java-based solution, but it’s very likely not going to be enough to actually matter.

For posterity, a reimplementation of your method:

def mulColorV(rgbHex, factV):
	from com.inductiveautomation.ignition.common import TypeUtilities
	from java.awt import Color
	javaColor = TypeUtilities.getColorFromString(rgbHex)
	hsl = Color.RGBtoHSB(javaColor.red, javaColor.green, javaColor.blue, None)
	hsl[2] = max(0.0, min(hsl[2] * factV, 1.0))
	hslColor = Color.getHSBColor(*hsl)
	return "#" + TypeUtilities.colorToHex(hslColor)
	
mulColorV("#100000", 0.2)
mulColorV("#100000", 2.0) 
1 Like

OTOH I might steal that code :wink: