Skip to content
Snippets Groups Projects
Color.py 3.57 KiB
# -*- coding: utf-8 -*-

# -*- coding: utf-8 -*-

import colorsys
import numpy

class Color(object):
    @staticmethod
    def hex_to_rgb(hex):
        """Turns a hex value #123456 into rgb (18, 52, 86)"""
        return tuple(int(hex[i:i+2], 16) for i in (0, 2 ,4))

    red = 0
    green = 0
    blue = 0

    hue = 0
    saturation = 0
    value = 0

    def __init__(self, rgb=None, hsv=None, hex=None):

        rgb_passed = type(rgb) is tuple
        hsv_passed = type(hsv) is tuple
        hex_passed = type(hex) is str

        if rgb_passed and hsv_passed and hex_passed:
            raise ValueError("Color can't be initialized with RGB, HSV and Hex at the same time.")
        elif hsv_passed:
            hue, saturation, value = hsv

            if not hue:
                hue = 0.0
            if not saturation:
                saturation = 0.0
            if not value:
                value = 0.0

            self.hue = hue
            self.saturation = saturation
            self.value = value
        elif rgb_passed:
            red, green, blue = rgb

            if not red:
                red = 0
            if not green:
                green = 0
            if not blue:
                blue = 0

            self.red = red
            self.green = green
            self.blue = blue
        elif hex_passed:
            red, green, blue = Color.hex_to_rgb(hex)

            self.red = red
            self.green = green
            self.blue = blue
        else:
            raise ValueError("No format was specified (RGB, HSV, Hex)")

    def _update_hsv(self):
        hue, saturation, value = colorsys.rgb_to_hsv(self.red/255.0, self.green/255.0, self.blue/255.0)
        super(Color, self).__setattr__('hue', hue * 360.0)
        super(Color, self).__setattr__('saturation', saturation)
        super(Color, self).__setattr__('value', value)

    def _update_rgb(self):
        red, green, blue = colorsys.hsv_to_rgb(self.hue / 360.0, self.saturation, self.value)
        super(Color, self).__setattr__('red', red * 255.0)
        super(Color, self).__setattr__('green', green * 255.0)
        super(Color, self).__setattr__('blue', blue * 255.0)

    def __setattr__(self, key, value):
        if key in ('red', 'green', 'blue'):
            if value > 255.0:
                value = value % 255.0
            super(Color, self).__setattr__(key, value)
            self._update_hsv()

        elif key in ('hue', 'saturation', 'value'):
            if key == 'hue' and (value >= 360.0 or value < 0):
                value = value % 360.0
            elif key != 'hue' and value > 1.0:
                value = 1.0
            super(Color, self).__setattr__(key, value)
            self._update_rgb()
        else:
            super(Color, self).__setattr__(key, value)

    def __repr__(self):
        return '<%s: red %f, green %f, blue %f, hue %f, saturation %f, value %f>' % (
                self.__class__.__name__,
                self.red,
                self.green,
                self.blue,
                self.hue,
                self.saturation,
                self.value,
            )

    def __str__(self):
            return "%d %d %d" % (
                int(self.red),
                int(self.green),
                int(self.blue),
            )

    def copy(self):
        return Color(self.red, self.green, self.blue)

    def hex(self):
        return "%.2X%.2X%.2X" % (self.red, self.green, self.blue)

    def rgb_tuple(self, p_int=False):
        if p_int:
            return (int(self.red), int(self.green), int(self.blue))
        else:
            return (self.red, self.green, self.blue)