Python- Is there a function or formula to find the complementary colour of a rgb code?

后端 未结 3 421
感情败类
感情败类 2021-01-05 15:08

I have tried to find a good formula in Python 3 to calculate the complementary colour of a rgb code eg. complementary of a = b. Is there any way to do this?

相关标签:
3条回答
  • 2021-01-05 15:23

    Here's how to calculate the complement of an RGB colour directly. It gives the same results as the algorithm using colorsys as shown in Iva Klass's answer, but in my tests it's about 50% faster. Note that it works for any RGB scheme, it doesn't matter whether the RGB components are integers or floats (as long as each component uses the same range!).

    The function hilo implements a simple sorting network to sort the RGB components.

    # Sum of the min & max of (a, b, c)
    def hilo(a, b, c):
        if c < b: b, c = c, b
        if b < a: a, b = b, a
        if c < b: b, c = c, b
        return a + c
    
    def complement(r, g, b):
        k = hilo(r, g, b)
        return tuple(k - u for u in (r, g, b))
    

    Here's a short demo, using PIL / Pillow.

    #!/usr/bin/env python3
    
    ''' Complement the colours in a RGB image 
    
        Written by PM 2Ring 2016.10.08
    '''
    
    import sys
    from PIL import Image
    
    # Sum of the min & max of (a, b, c)
    def hilo(a, b, c):
        if c < b: b, c = c, b
        if b < a: a, b = b, a
        if c < b: b, c = c, b
        return a + c
    
    def complement(r, g, b):
        k = hilo(r, g, b)
        return tuple(k - u for u in (r, g, b))
    
    def complement_image(iname, oname):
        print('Loading', iname)
        img = Image.open(iname)
        #img.show()
    
        size = img.size
        mode = img.mode
        in_data = img.getdata()
    
        print('Complementing...')
        out_img = Image.new(mode, size)
        out_img.putdata([complement(*rgb) for rgb in in_data])
        out_img.show()
        out_img.save(oname)
        print('Saved to', oname)
    
    def main():
        if len(sys.argv) == 3:
            complement_image(*sys.argv[1:])
        else:
            fmt = 'Complement colours.\nUsage: {} input_image output_image'
            print(fmt.format(sys.argv[0]))
    
    if __name__ == '__main__':
        main()
    

    input image

    source image

    output image

    output image


    Here's a Numpy version of complement_image. On my machine it processes the "Glasses" image about 3.7 times faster than the previous version.

    import numpy as np
    
    def complement_image(iname, oname):
        print('Loading', iname)
        img = Image.open(iname)
        #img.show()
    
        in_data = np.asarray(img)
        #print(in_data.shape)
    
        print('Complementing...')
        lo = np.amin(in_data, axis=2, keepdims=True)
        hi = np.amax(in_data, axis=2, keepdims=True)
        out_data = (lo + hi) - in_data
    
        out_img = Image.fromarray(out_data)
        #out_img.show()
        out_img.save(oname)
        print('Saved to', oname)
    
    0 讨论(0)
  • 2021-01-05 15:29

    I don't think there is ready solution for this, but there is a colorsys module in standard library, it can help.

    I think you first need to convert RGB into HSV or HSL, then "rotate" hue, and convert back to RGB, if you need. For example (I'm not sure about proper rotating):

    from colorsys import rgb_to_hsv, hsv_to_rgb
    
    def complementary(r, g, b):
       """returns RGB components of complementary color"""
       hsv = rgb_to_hsv(r, g, b)
       return hsv_to_rgb((hsv[0] + 0.5) % 1, hsv[1], hsv[2])
    
    0 讨论(0)
  • 2021-01-05 15:33
    r,g,b = [25,25,25]
    
    def get_complementary(color):
        color = color[1:]
        color = int(color, 16)
        comp_color = 0xFFFFFF ^ color
        comp_color = "#%06X" % comp_color
        return comp_color
    hex_val = "#%02x%02x%02x" % (r,g,b)
    h = get_complementary(hex_val)
    print("Complementary color",h)
    h = h.lstrip('#')
    print('RGB =', tuple(int(h[i:i+2], 16) for i in (0, 2, 4)))
    

    output:

    Complementary color #E6E6E6

    RGB = (230, 230, 230)

    0 讨论(0)
提交回复
热议问题