Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Moving through a sepia color set, from dark to light ?
Message
 
To
28/05/2010 15:47:48
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Environment versions
Visual FoxPro:
VFP 9 SP2
Miscellaneous
Thread ID:
01466438
Message ID:
01466451
Views:
66
Francois,

I have some old functions to deal with this issue, part of them I mentioned in this thread Message #1022826, the complete class is this:
*******************************************************************************************************************
*                                                                                                                 *
* 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
Enddefine
It 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,
>
>I am looking for a way to programmatically deliver a set of sepia-based colors.
>
>Assuming I have a base sepia color, say RGB(112,66,20), I can try something like GETCOLOR(RGB(112,66,20)) and move through various tones from DARK sepia to LIGHT with the Windows color box. How can I replicate that in code ?
>
>Sure, that must be something someone among the UT has bumped into whilst coding an graphical application:)
>
>It may be simple but I am stuck at this stage!
"The five senses obstruct or deform the apprehension of reality."
Jorge L. Borges?

"Premature optimization is the root of all evil in programming."
Donald Knuth, repeating C. A. R. Hoare

"To die for a religion is easier than to live it absolutely"
Jorge L. Borges
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform