Converting RGB and RGBA to HEX

Binary Adventures

I started out with a color palette that had the individual colors defined as RGB values, while I needed the HEX values, as well as a second value by applying a certain percentage of transparency to the original colour.

The end result (containing both original color and semi-transparent complement) then has to be presented in an HTML file for easy reference, a large square for ever colour and the corresponding HEX value displayed on top of it.

Approach

Conversion to HEX

The color values were transformed into a Pandas DataFrame and subsequently converted to their HEX value using the Python Colour library. This required an intermediate step whereby the individual values for R, G and B are recalculated to a value in the range from 0 to 1.

rgb_spectrum = """R G   B
116 138 180
156 198 112
…"""

df = pd.read_csv(StringIO(rgb_spectrum), sep='\t')
df = df / 255
df['hex'] = df.apply(lambda x: colour.rgb2hex((x.R, x.G, x.B)), axis=1)

Transparency

For the semi-transparent colour, we first define a transparency ratio. Next, we calculate the values for R, G and B using the formula below:

# 50% transparency
trans_ratio =.5
# Temporary dataframe to capture the RGB values for our transparent color
df_trans = ((1-trans_ratio) * 1) + (trans_ratio * df)
# Conversion to HEX, adding the value to the original dataframe as a new column
df['hex_trans'] = df_trans.apply(lambda x: colour.rgb2hex((x.R, x.G, x.B)), axis=1)

This calculation is discussed in this SO answer and basically comes down to:

Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R)
Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G)
Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)

Where Source is the original colour, Source.A is the transparency ratio, and BGColor is the background color (1 = white, 0 = black).

Rendering the palette in HTML

We’ll use the yattag library to create the HTML content using context managers.

# Extract the hex value for the colour and transparant colour from the DataFrame
palette = df.loc[:,['hex', 'hex_trans']].to_dict('records')

# Create the HTML document with yattag
from yattag import Doc

doc, tag, text = Doc().tagtext()

doc.asis('<!DOCTYPE html>')

with tag('html'):
    with tag('head'):
        with tag('style'):
            text("""table, th, td {
                    border: 1px solid white;
                    border-collapse: collapse;
                }
                th, td {
                    text-align: center;
                }
                td {
                    height: 100px;
                    width: 100px;
                }""")
    with tag('body'):
        with tag('table'):
            # Header
            with tag('tr'):
                with tag('th'):
                    text('Base')
                with tag('th'):
                    text('Transparent')

            # Palette rendering
            for entry in palette:
                with tag('tr'):
                    with tag('td', style='background-color:' + entry['hex']):
                        text(entry['hex'].upper())
                    with tag('td', style='background-color:' + entry['hex_trans']):
                        text(entry['hex_trans'].upper())

# Write the HTML to file
with open('palette_spectrum.html', 'w') as f:
    f.write(indent(doc.getvalue()))

Result

5A838F071F4C9091A6360507FF5812BB.png