ArcGIS python HSV to RGB colour conversion

343
1
02-12-2024 07:06 PM
JohnMcGlynn
Occasional Contributor

I am trying to populate 3 fields in a feature class with the symbology colour in RGB.
My conversion code takes the H, S and V values given by the layer.symbology.renderer.symbol.color function.

A sample of the output from the color function is:  {'HSV': [61, 50, 55, 100]}

The values must be munged to cater for the ArcGIS colour model ;

My code is:

    def colourHSVtoRGB(self,H,S,V):
        # The ArcGIS HSV model is strange - Hue 0-240, Saturation 0 - 255, Value 0 - 255
        from matplotlib.colors import hsv_to_rgb
        # Convert hval to 360 and make it 0 - 1
        hval = 3.6 * (H / 240)
        sval = S / 255
        vval = V / 255

        invals = [hval, sval, vval]
        rg = hsv_to_rgb(invals)
        R = rg[0]
        G = rg[1]
        B = rg[2]

        # Convert to 0 - 255
        R = int(round((R * 255), 0))
        G = int(round((G * 255), 0))
        B = int(round((B * 255), 0))

 

Unfortunately this gives the incorrect RGB values.

From a colour web site, the RGB for HSV = 61, 50, 55 should be 139, 140, 70, which also looks like the correct colour.

My function outputs RGB values;  49, 55, 44 - clearly wrong.
The input values to the matplotlib function are all 0 - 1. I'm sure my interpretation of the calculation for this input could use some improvement.

Thanks,

J

 

Tags (2)
1 Reply
JohnMcGlynn
Occasional Contributor

I was able to fix this by using the algorithm at rapidtables.

Unlike the data given in the ESRI documentation (hue = 0 - 240, saturation = 0 - 255, value = 0 - 255) the actual HSV format is hue 0 - 360, saturation 0 - 100, value 0 - 100

The code is now:

    def colourHSVtoRGB(self,H,S,V):
        # The ArcGIS HSV model is - Hue 0-360, Saturation Pct, Value Pct
        # Algorithm from https://www.rapidtables.com/convert/color/hsv-to-rgb.html
        hval = H
        if hval == 360:
            hval = 0
        sval = S / 100
        vval = V / 100

        C = sval * vval
        tr = abs((hval / 60 % 2) - 1)
        X = C * (1 - tr)
        if 0 <= H and H < 60:
            R = C
            G = X
            B = 0
        elif 60 <= H and H < 120:
            R = X
            G = C
            B = 0
        elif 120 <= H and H < 180:
            R = 0
            G = C
            B = X
        elif 180 <= H and H < 240:
            R = 0
            G = X
            B = C
        elif 240 <= H and H < 300:
            R = X
            G = 0
            B = C
        elif 300 <= H and H < 360:
            R = C
            G = 0
            B = X

        m = vval - C
        R = int(round(255 * (R + m),0))
        G = int(round(255 * (G + m),0))
        B = int(round(255 * (B + m),0))

        return R, G, B

 John