NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

color.py (7187B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\chroma\color.py
      2 from __future__ import division
      3 import collections
      4 import mathext
      5 from chroma.conversion import hsb_to_rgb, rgb_to_hsb
      6 
      7 class Color(collections.Sequence):
      8 
      9     def __init__(self, r, g, b, a = 1.0):
     10         for arg in (r,
     11          g,
     12          b,
     13          a):
     14             if not isinstance(arg, (float, int)):
     15                 raise TypeError('Color components should be floats, not {}'.format(type(arg).__name__))
     16 
     17         self._r = float(r)
     18         self._g = float(g)
     19         self._b = float(b)
     20         self._a = float(a)
     21 
     22     @classmethod
     23     def from_rgba(cls, r, g, b, a = 1.0):
     24         return cls(r, g, b, a)
     25 
     26     @classmethod
     27     def from_rgba_8bit(cls, r, g, b, a = 255):
     28         return cls(mathext.clamp(r, 0, 255) / 255, mathext.clamp(g, 0, 255) / 255, mathext.clamp(b, 0, 255) / 255, mathext.clamp(a, 0, 255) / 255)
     29 
     30     @classmethod
     31     def from_hex(cls, value):
     32         if not isinstance(value, (str, unicode)):
     33             raise ValueError('Hex color value must be a string')
     34         if value.startswith('#'):
     35             value = value[1:]
     36         if len(value) == 8:
     37             a = int(value[0:2], 16) / 255
     38             r = int(value[2:4], 16) / 255
     39             g = int(value[4:6], 16) / 255
     40             b = int(value[6:8], 16) / 255
     41         elif len(value) == 6:
     42             a = 1.0
     43             r = int(value[0:2], 16) / 255
     44             g = int(value[2:4], 16) / 255
     45             b = int(value[4:6], 16) / 255
     46         elif len(value) == 3:
     47             a = 1.0
     48             r = int(value[0] * 2, 16) / 255
     49             g = int(value[1] * 2, 16) / 255
     50             b = int(value[2] * 2, 16) / 255
     51         else:
     52             raise ValueError('Invalid hex color value provided: {!r}'.format(value))
     53         return cls(r, g, b, a)
     54 
     55     @classmethod
     56     def from_hsb(cls, h, s, b, a = 1.0):
     57         red, green, blue = hsb_to_rgb(h, s, b)
     58         return cls(red, green, blue, a)
     59 
     60     @classmethod
     61     def from_any(cls, value):
     62         if isinstance(value, Color) or hasattr(value, 'rgba'):
     63             return cls(*value.rgba)
     64         if isinstance(value, (str, unicode)):
     65             return cls.from_hex(value)
     66         try:
     67             return cls(*value)
     68         except Exception:
     69             pass
     70 
     71         raise ValueError('Unknown color value: {!r}'.format(value))
     72 
     73     @property
     74     def r(self):
     75         return self._r
     76 
     77     @property
     78     def red(self):
     79         return self._r
     80 
     81     @property
     82     def g(self):
     83         return self._g
     84 
     85     @property
     86     def green(self):
     87         return self._g
     88 
     89     @property
     90     def b(self):
     91         return self._b
     92 
     93     @property
     94     def blue(self):
     95         return self._b
     96 
     97     @property
     98     def a(self):
     99         return self._a
    100 
    101     @property
    102     def alpha(self):
    103         return self._a
    104 
    105     @property
    106     def opacity(self):
    107         return self._a
    108 
    109     @property
    110     def rgb(self):
    111         return (self._r, self._g, self._b)
    112 
    113     @property
    114     def rgb_8bit(self):
    115         return (int(round(self._r * 255.0)), int(round(self._g * 255.0)), int(round(self._b * 255.0)))
    116 
    117     @property
    118     def rgba(self):
    119         return (self._r,
    120          self._g,
    121          self._b,
    122          self._a)
    123 
    124     @property
    125     def rgba_8bit(self):
    126         return (int(round(self._r * 255.0)),
    127          int(round(self._g * 255.0)),
    128          int(round(self._b * 255.0)),
    129          int(round(self._a * 255.0)))
    130 
    131     @property
    132     def hex_argb(self):
    133         r, g, b, a = self.rgba_8bit
    134         return u'#{:02x}{:02x}{:02x}{:02x}'.format(a, r, g, b)
    135 
    136     @property
    137     def hex_rgb(self):
    138         return u'#{:02x}{:02x}{:02x}'.format(*self.rgb_8bit)
    139 
    140     @property
    141     def hsb(self):
    142         return rgb_to_hsb(self._r, self._g, self._b)
    143 
    144     @property
    145     def hue(self):
    146         hue, _, _ = rgb_to_hsb(self._r, self._g, self._b)
    147         return hue
    148 
    149     @property
    150     def saturation(self):
    151         _, saturation, _ = rgb_to_hsb(self._r, self._g, self._b)
    152         return saturation
    153 
    154     @property
    155     def brightness(self):
    156         _, _, brightness = rgb_to_hsb(self._r, self._g, self._b)
    157         return brightness
    158 
    159     @property
    160     def luminance(self):
    161         return 0.2126 * self.r + 0.7152 * self.g + 0.0722 * self.b
    162 
    163     @property
    164     def is_grayscale(self):
    165         _, saturation, _ = self.hsb
    166         return mathext.is_almost_zero(saturation)
    167 
    168     def as_argb_int32(self):
    169         return int(round(mathext.clamp(self._a, 0.0, 1.0) * 255)) << 24 | int(round(mathext.clamp(self._r, 0.0, 1.0) * 255)) << 16 | int(round(mathext.clamp(self._g, 0.0, 1.0) * 255)) << 8 | int(round(mathext.clamp(self._b, 0.0, 1.0) * 255))
    170 
    171     def with_red(self, red):
    172         return Color(red, self._g, self._b, self._a)
    173 
    174     def with_green(self, green):
    175         return Color(self._r, green, self._b, self._a)
    176 
    177     def with_blue(self, blue):
    178         return Color(self._r, self._g, blue, self._a)
    179 
    180     def with_alpha(self, alpha):
    181         return Color(self._r, self._g, self._b, alpha)
    182 
    183     def with_hue(self, hue):
    184         hue = mathext.clamp(hue, 0.0, 1.0)
    185         _, saturation, brightness = rgb_to_hsb(self._r, self._g, self._b)
    186         r, g, b = hsb_to_rgb(hue, saturation, brightness)
    187         return Color(r, g, b, a=self._a)
    188 
    189     def with_saturation(self, saturation):
    190         saturation = mathext.clamp(saturation, 0.0, 1.0)
    191         hue, _, brightness = rgb_to_hsb(self._r, self._g, self._b)
    192         r, g, b = hsb_to_rgb(hue, saturation, brightness)
    193         return Color(r, g, b, a=self._a)
    194 
    195     def with_brightness(self, brightness):
    196         brightness = mathext.clamp(brightness, 0.0, 1.0)
    197         hue, saturation, _ = rgb_to_hsb(self._r, self._g, self._b)
    198         r, g, b = hsb_to_rgb(hue, saturation, brightness)
    199         return Color(r, g, b, a=self._a)
    200 
    201     def with_capped_brightness(self, min_brightness = 0.0, max_brightness = 1.0):
    202         if self.brightness < min_brightness:
    203             return Color.from_hsb(self.hue, self.brightness, min_brightness)
    204         elif self.brightness > max_brightness:
    205             return Color.from_hsb(self.hue, self.brightness, max_brightness)
    206         else:
    207             return self
    208 
    209     def __eq__(self, other):
    210         if not isinstance(other, Color):
    211             try:
    212                 other = Color.from_any(other)
    213             except ValueError:
    214                 return NotImplemented
    215 
    216         return mathext.is_close(self._r, other.r) and mathext.is_close(self._g, other.g) and mathext.is_close(self._b, other.b) and mathext.is_close(self._a, other.a)
    217 
    218     def __ne__(self, other):
    219         if not isinstance(other, Color):
    220             try:
    221                 other = Color.from_any(other)
    222             except ValueError:
    223                 return NotImplemented
    224 
    225         return not mathext.is_close(self._r, other.r) or not mathext.is_close(self._g, other.g) or not mathext.is_close(self._b, other.b) or not mathext.is_close(self._a, other.a)
    226 
    227     def __hash__(self):
    228         return hash(self.rgba)
    229 
    230     def __str__(self):
    231         return self.hex_argb
    232 
    233     def __repr__(self):
    234         return u'Color(r={!r}, g={!r}, b={!r}, a={!r})'.format(*self.rgba)
    235 
    236     def __getitem__(self, item):
    237         return self.rgba[item]
    238 
    239     def __len__(self):
    240         return 4