******************************************************************************************************************* * * * Class ColorFunctions - A collection of color-related functions. * * * * Methods: * * * * RGBComp - Modifies the parameters for red, green and blue to match the rgb value of the firs param. * * newColorObject - Returns a color object, with red, green and blue properties * * hue2rgbVal - This is an internal function used by hsl2rgbVal * * hsl2rgbVal - Returns a RGB value given the Hue, Saturation an Luminosity * * rgb2hsl - Converts a RGB value to a HSL value (Red, Green, Blue to Hue, Saturation, Luminosity) * * getHSLProp - This function returns the Hue, Saturation or Luminosity of a HSL color * * getRGBProp - This function returns the Red, Green or blue component of a RGB color * * getColorRed - Returns the Red component of an RGB value * * getColorGreen - Returns the Green component of an RGB value * * getColorBlue - Returns the Blue component of an RGB value * * getColorHue - Returns the Hue component of an RGB value * * getColorSaturation - Returns the Saturation component of an RGB value * * getColorLum - Returns the Luminosity component of an RGB value * * adjustRGBLum - Adjust the luminosity of an RGB value by a fixed value passed as parameter * * setRGBLum - Sets the luminosity value * * RGBValToRGBStr - Returns the RGB set of values as a string * * * ******************************************************************************************************************* Define Class ColorFunctions As Custom *+ RGBComp Function RGBComp(tnColor) Local lnRed, lnGreen, lnBlue lnRed = tnColor % 256 lnGreen = Bitrshift(tnColor, 8) % 256 lnBlue = Bitrshift(tnColor, 16) % 256 Return This.newColorObject(lnRed, lnGreen, lnBlue) ENDFUNC *+ newColorObject Function newColorObject(tnRed, tnGreen, tnBlue) Local loColor loColor = Newobject('Empty') AddProperty(loColor, 'Red', Iif(Vartype(tnRed)='N' And Between(tnRed, 0, 255), tnRed, 0)) AddProperty(loColor, 'Green', Iif(Vartype(tnGreen)='N' And Between(tnGreen, 0, 255), tnGreen, 0)) AddProperty(loColor, 'Blue', Iif(Vartype(tnBlue)='N' And Between(tnBlue, 0, 255), tnBlue, 0)) Return loColor Endfunc *+ hue2rgbVal Function hue2rgbVal(tn1, tn2, lnHue) Local lnReturn * range check: note values passed add/subtract thirds of range lnHue = Iif(lnHue < 0, lnHue + _HLSMAX, lnHue) lnHue = Iif(lnHue > _HLSMAX, lnHue - _HLSMAX, lnHue) * return r,g, or b value from this trio Do Case Case lnHue < (_HLSMAX / 6) lnReturn = tn1 + (((tn2 - tn1) * lnHue + (_HLSMAX / 12)) / (_HLSMAX / 6)) Case lnHue < (_HLSMAX / 2) lnReturn = tn2 Case lnHue < (_HLSMAX * 2) / 3 lnReturn = tn1 + (((tn2 - tn1) * (((_HLSMAX * 2) / 3) - lnHue) + (_HLSMAX / 12)) / (_HLSMAX / 6)) Otherwise lnReturn = tn1 Endcase Return Int(lnReturn) Endfunc *+ hsl2rgbVal Function hsl2rgbVal(tnHue, tnSat, tnLum) Local lnRed, lnGreen, lnBlue, lnHue, lnSat, lnLum, i, F, p, q, T, lnMagic1, lnMagic2 If tnSat = 0 && _ACHROMATIC lnLum = Round(tnLum * _RGBMAX / _HLSMAX, 0) Return Rgb(lnLum, lnLum, lnLum) Endif * Chromatic lnLum = tnLum lnSat = tnSat * normalize hue to lie in 0<=h<360 lnHue = tnHue % 360 lnHue = Iif(lnHue < 0, lnHue * 360, 0) + lnHue * Set up magic numbers If (lnLum <= (_HLSMAX / 2)) lnMagic2 = (lnLum * (_HLSMAX + lnSat) + (_HLSMAX / 2)) / _HLSMAX Else lnMagic2 = lnLum + lnSat - ((lnLum * lnSat) + (_HLSMAX / 2)) / _HLSMAX Endif lnMagic1 = 2 *lnLum - lnMagic2 * Get RGB, change units from _HLSMAX to _RGBMAX lnRed = (This.hue2rgbVal(lnMagic1, lnMagic2, lnHue + (_HLSMAX / 3)) * _RGBMAX +(_HLSMAX / 2)) / _HLSMAX lnGreen = (This.hue2rgbVal(lnMagic1, lnMagic2, lnHue) * _RGBMAX + (_HLSMAX / 2)) / _HLSMAX lnBlue = (This.hue2rgbVal(lnMagic1, lnMagic2, lnHue - (_HLSMAX/3)) * _RGBMAX +(_HLSMAX / 2)) / _HLSMAX * Adjust for round errors lnRed = Int(Max(Min(lnRed, 255), 0)) lnGreen = Int(Max(Min(lnGreen, 255), 0)) lnBlue = Int(Max(Min(lnBlue, 255), 0)) Return Rgb(lnRed, lnGreen, lnBlue) Endfunc *+ rgb2hsl Function rgb2hsl(tnRed, tnGreen, tnBlue) Local lnMax, lnMin, lnHue, lnSaturation, lnLum, lnDiff, lnRDelta, lnGDelta, lnBDelta lnMax = Max(tnRed, tnGreen, tnBlue) lnMin = Min(tnRed, tnGreen, tnBlue) lnDiff = (lnMax-lnMin) lnLum = (((lnMax + lnMin) * _HLSMAX) + _RGBMAX) / (2 * _RGBMAX) If lnMax = lnMin && _ACHROMATIC lnSaturation = 0 lnHue = _ACHROMATIC Else && chromatic If (lnLum <= (_HLSMAX / 2)) lnSaturation = ((lnDiff * _HLSMAX) + ((lnMax + lnMin) / 2)) / (lnMax + lnMin) Else lnSaturation = ((lnDiff * _HLSMAX) + (2 * _RGBMAX - lnMax - lnMin) / 2) / (2 * _RGBMAX - lnMax - lnMin) Endif lnRDelta = (((lnMax - tnRed) * (_HLSMAX / 6)) + ((lnDiff) / 2)) / (lnDiff) lnGDelta = (((lnMax - tnGreen) * (_HLSMAX / 6)) + ((lnDiff) / 2)) / (lnDiff) lnBDelta = (((lnMax - tnBlue) * (_HLSMAX / 6)) + ((lnDiff) / 2)) / (lnDiff) Do Case Case tnRed = lnMax lnHue = lnBDelta - lnGDelta Case tnGreen = lnMax lnHue = (_HLSMAX / 3) + lnRDelta - lnBDelta Case tnBlue = lnMax lnHue = ((2 * _HLSMAX) / 3) + lnGDelta - lnRDelta Endcase lnHue = Int(lnHue) + Iif(lnHue < 0, _HLSMAX, Iif(lnHue > _HLSMAX, -_HLSMAX, 0)) Endif Return Alltrim(Str(lnHue)) + ',' + Alltrim(Str(Int(lnSaturation))) + ',' + Alltrim(Str(Int(lnLum))) Endfunc *+ getHSLProp Function getHSLProp(tcHSL, tnProperty) Local laValues(1), lcHSL, lnReturn, lnProperty * If property is not given, defaults to Hue lcHSL = Iif(Vartype(tcHSL) = 'C', tcHSL, '') lnProperty = Iif(Vartype(tnProperty) = 'N' And Between(tnProperty, 1, 3), tnProperty, 3) lnReturn = -1 If Alines(laValues, lcHSL, ',') = 3 lnReturn = Val(laValues[lnProperty]) Endif Return lnReturn Endfunc *+ getRGBProp Function getRGBProp(tnRGB, tnProperty) Local loColor, lnProperty, lnReturn * If property is not given, defaults to Red lnProperty = Iif(Vartype(tnProperty)='N' And Between(tnProperty, 1, 3), tnProperty, 1) loColor = This.RGBComp(tnRGB) lnReturn = Iif(tnProperty = 3, loColor.Blue, Iif(tnProperty = 2, loColor.Green, loColor.Red)) Return lnReturn Endfunc *+ getColorRed Function getColorRed(tnRGB) Return This.getRGBProp(tnRGB, 1) Endfunc *+ getColorGreen Function getColorGreen(tnRGB) Return This.getRGBProp(tnRGB, 2) Endfunc *+ getColorBlue Function getColorBlue(tnRGB) Return This.getRGBProp(tnRGB, 3) Endfunc *+ getColorHue Function getColorHue(tcHSL) Return This.getHSLProp(tcHSL, 1) Endfunc *+ getColorSaturation Function getColorSaturation(tcHSL) Return This.getHSLProp(tcHSL, 2) Endfunc *+ getColorLum Function getColorLum(tcHSL) Return This.getHSLProp(tcHSL, 3) Endfunc *+ adjustRGBLum Function adjustRGBLum(tnRGB, tnInc) Local lnLum, lcHSL, lnReturn, lnInc, loColor lnInc = Iif(tnRGB % 255 = 0, 2, 1) * tnInc loColor = This.RGBComp(tnRGB) lcHSL = This.rgb2hsl(loColor.Red, loColor.Green, loColor.Blue) lnLum = This.getHSLProp(lcHSL, 3) + lnInc lnLum = Iif(lnLum < 0, lnLum + 2 * lnInc, Iif(lnLum > _HLSMAX, lnLum - 2 * lnInc, lnLum)) lnReturn = This.hsl2rgbVal(This.getColorHue(lcHSL), This.getColorSaturation(lcHSL), lnLum) Return lnReturn Endfunc *+ setRGBLum Function setRGBLum(tnRGB, tnLum) Local lnLum, lcHSL, lnReturn, lnInc, loColor loColor = This.RGBComp(tnRGB) lcHSL = This.rgb2hsl(loColor.Red, loColor.Green, loColor.Blue) lnLum = tnLum lnReturn = This.hsl2rgbVal(This.getColorHue(lcHSL), This.getColorSaturation(lcHSL), lnLum) Return lnReturn Endfunc *+ RGBValToRGBStr Function RGBValToRGBStr(tnRGB, tcSeparator) Local loColor, lcSep lcSep = Iif(Vartype(tcSeparator)='C', tcSeparator, ',') loColor = This.RGBComp(tnRGB) Return Transform(loColor.Red, '@L ###') + lcSep + Transform(loColor.Green, '@L ###') + lcSep + Transform(loColor.Blue, '@L ###') Endfunc *+ CYMKToRGB Function CYMKToRGB(tnCyan, tnYellow, tnMagenta, tnBlack) Return This.newColorObject(1 - tnCyan - tnBlack, 1 - tnMagenta - tnBlack, 1 - tnYellow - tnBlack) Endfunc *+ CYMKToRGBValue Function CYMKToRGBValue(tnCyan, tnYellow, tnMagenta, tnBlack) Return Rgb(1 - tnCyan - tnBlack, 1 - tnMagenta - tnBlack, 1 - tnYellow - tnBlack) Endfunc EnddefineIt is an old class, and I already saw some things that can be improved, like error handling, but to do what you want you do something like this:
loCF = Newobject('ColorFunctions', 'The PRG where you created the class') ? loCF.AdjustRGBLum(RGB(112,66,20), +30)>Hi,