/[gzz]/gzz/gfx/libcolor/spaces.py
ViewVC logotype

Diff of /gzz/gfx/libcolor/spaces.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by jvk, Mon Sep 30 10:18:54 2002 UTC revision 1.10 by jvk, Mon Oct 14 17:49:30 2002 UTC
# Line 107  def getRandomColor2(minL, maxL, rnd): Line 107  def getRandomColor2(minL, maxL, rnd):
107      return LABclamp(rgb)      return LABclamp(rgb)
108    
109    
110    def inUnit(vec):
111        """Tests whether the vector is inside the unit cube [0,1]^n"""
112        return len(filter((lambda x: x<0 or x>1), vec)) == 0
113        
114    
115  def LABclamp(rgb):  def LABclamp(rgb):
116      """Clamp a RGB color into [0,1]^3 towards the CIELAB L-axis      """Clamp a RGB color into [0,1]^3 towards the CIELAB L-axis
117    
118      rgb: the color in RGB709      rgb: the color in RGB709
119      returns: the clamped color in RGB709      returns: the clamped color in RGB709
120      """      """
121      if len(filter((lambda x: x<0 or x>1), rgb)) == 0:      if inUnit(rgb):
122          return rgb          return rgb
123    
124      (L,a,b) = RGBtoLAB(rgb)      (L,a,b) = RGBtoLAB(rgb)
# Line 122  def LABclamp(rgb): Line 127  def LABclamp(rgb):
127      bit = .5      bit = .5
128      for iter in range(0,10):      for iter in range(0,10):
129          rgb = LABtoRGB([L,(r+bit)*a,(r+bit)*b])          rgb = LABtoRGB([L,(r+bit)*a,(r+bit)*b])
130          if len(filter((lambda x: x<0 or x>1), rgb)) == 0:          if inUnit(rgb):
131              r = r + bit              r = r + bit
132          bit = bit * .5          bit = bit * .5
133      return LABtoRGB([L,r*a,r*b])      return LABtoRGB([L,r*a,r*b])
134    
135    
136    # The YST color space below is a linear color space with
137    # a lightness component and a color plane vector whose angle and
138    # radius specify the hue and saturation, respectively.
139    # Opposite colors are 180 degrees apart.
140    #
141    # The Y component is the CIE Y lightness (but the weights can be changed) and
142    # the ST-plane has the RGB primaries 120 (R = 0, G = 120, B = 240) degrees apart
143    # at radius 1.
144    #    
145    # Lightness weights of the RGB primaries used in YST color space functions
146    Wr = 0.212671
147    Wg = 0.715160
148    Wb = 0.072169
149    
150    def YSTtoRGB(v):
151        n = 1.0 / (Wr+Wg+Wb)
152        mat =  [ [n, n*(Wg+Wb), n*(Wb - Wg)  / math.sqrt(3) ],
153                 [n, n*(-Wr), n*(2*Wb + Wr) / math.sqrt(3) ],
154                 [n, n*(-Wr), n*-(2*Wg + Wr) / math.sqrt(3) ] ]
155        
156        return [ mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2],
157                 mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2],
158                 mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] ]
159    
160    def RGBtoYST(v):
161        mat = [[ Wr, Wg, Wb ],
162               [ 1, -.5, -.5],
163               [ 0, .5*math.sqrt(3), -.5*math.sqrt(3) ]]
164    
165        return [ mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2],
166                 mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2],
167                 mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] ]
168    
169    def maxYSTsat(YST):
170        """Return the maximum saturation factor in RGB cube of the given color"""
171    
172        # Split into "lightness" and "color" components
173        Y = YSTtoRGB((YST[0],0,0))
174        vec = YSTtoRGB((0,YST[1],YST[2]))
175    
176        assert 0 <= Y[0] == Y[1] == Y[2] <= 1
177    
178        return min( ((vec[0] > 0) - Y[0]) / vec[0],
179                    ((vec[1] > 0) - Y[1]) / vec[1],
180                    ((vec[2] > 0) - Y[2]) / vec[2] )
181    
182            
183    def clampSat(rgb):
184        """Clamp an RGB color keeping hue and lightness constant"""
185    
186        if inUnit(rgb):
187            return rgb
188    
189        (Y,S,T) = RGBtoYST(rgb)
190    
191        r = maxYSTsat((Y,S,T))
192    
193        return YSTtoRGB((Y,r*S,r*T))
194    
195    
196    
197    def YSThue(RGB):
198        YST = RGBtoYST(RGB)
199        return math.atan2(YST[2],YST[1])
200    
201    
202    
203    
204    """
205    # Kluge: Emulate LAB color space using YST hues
206    angles = map(YSThue, colors)
207    angles = map(lambda a: a + (a < 0) * 2 * math.pi, angles)
208    angles.sort()
209    angles += [angles[0] + 2 * math.pi]
210    
211    LABclamp = clampSat
212    LABtoRGB = lambda lab: YSTtoRGB((lab[0]*.01,lab[1]*.01,lab[2]*.01))
213    
214    def RGBtoLAB(rgb):
215        yst = RGBtoYST(rgb)
216        return [ -16 + 116 * pow(yst[0], 1./3), 100 * yst[1], 100 * yst[2] ]
217    
218    def LABtoRGB(lab):
219        yst = [ pow((lab[0] + 16.0) / 116, 3), lab[1] / 100.0, lab[2] / 100.0 ]
220        return YSTtoRGB(yst)
221    """

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26