# The MASM Forum

## Projects => Rarely Used Projects => RosAsm => Topic started by: guga on June 01, 2014, 01:51:09 PM

Title: RGBRotate
Post by: guga on June 01, 2014, 01:51:09 PM
This is an excellent example of rotating the hue using only matrices. It is way better transformation.

Code: [Select]
`;;http://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-colorThe RGB color space describes a cube. It is possible to rotate this cube around the diagonal axis from (0,0,0) to (255,255,255)to effect a change of hue.Note that some of the results will lie outside of the 0 to 255 range and will need to be clipped.I finally got a chance to code this algorithm.It's in Python but it should be easy to translate to the language of your choice.The formula for 3D rotation came from http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angleEdit: If you saw the code I posted previously, please ignore it.I was so anxious to find a formula for the rotation that I converted a matrix-based solution into a formula, not realizingthat the matrix was the best form all along.I've still simplified the calculation of the matrix using the constant sqrt(1/3) for axis unit vector values,but this is much closer in spirit to the reference and simpler in the per-pixel calculation apply as well.from math import sqrt,cos,sin,radiansdef clamp(v):    if v < 0:        return 0    if v > 255:        return 255    return int(v + 0.5)class RGBRotate(object):    def __init__(self):        self.matrix = [[1,0,0],[0,1,0],[0,0,1]]    def set_hue_rotation(self, degrees):        cosA = cos(radians(degrees))        sinA = sin(radians(degrees))        self.matrix = cosA + (1.0 - cosA) / 3.0        self.matrix = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA        self.matrix = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA        self.matrix = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA        self.matrix = cosA + 1./3.*(1.0 - cosA)        self.matrix = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA        self.matrix = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA        self.matrix = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA        self.matrix = cosA + 1./3. * (1.0 - cosA)    def apply(self, r, g, b):        rx = r * self.matrix + g * self.matrix + b * self.matrix        gx = r * self.matrix + g * self.matrix + b * self.matrix        bx = r * self.matrix + g * self.matrix + b * self.matrix        return clamp(rx), clamp(gx), clamp(bx);;[RotationMatrix: RotationMatrix.Data0_0: R\$ 0 RotationMatrix.Data0_1: R\$ 0 RotationMatrix.Data0_2: R\$ 0 RotationMatrix.Data1_0: R\$ 0 RotationMatrix.Data1_1: R\$ 0 RotationMatrix.Data1_2: R\$ 0 RotationMatrix.Data2_0: R\$ 0 RotationMatrix.Data2_1: R\$ 0 RotationMatrix.Data2_2: R\$ 0][Float_SquareRoot_OneThird: R\$ 0.577350269189625764509148780501957455647601751270126876018602] ; sqrt(1/3)[TmpRotate.Red: R\$ 0][TmpRotate.Green: R\$ 0][TmpRotate.Blue: R\$ 0][TmpAngle: R\$ 0][TmpRotateRatio: R\$ 0]Proc RGBRotate:    Arguments @pColorData, @Angle    Local @TmpStorage, @TmpAngle, @TmpColorRed, @TmpColorGreen, @TmpColorBlue    Uses ebx, esi    mov esi D@pColorData    lea ebx D@TmpColorRed | move D\$ebx D\$esi    lea ebx D@TmpColorGreen | move D\$ebx D\$esi    lea ebx D@TmpColorBlue | move D\$ebx D\$esi    lea ebx D@TmpStorage    movzx eax B\$esi+RGBTRIPLE.rgbtRedDis | mov D\$ebx eax | fild F\$ebx | fstp R\$TmpRotate.Red    movzx eax B\$esi+RGBTRIPLE.rgbtGreenDis | mov D\$ebx eax | fild F\$ebx | fstp R\$TmpRotate.Green    movzx eax B\$esi+RGBTRIPLE.rgbtBlueDis | mov D\$ebx eax | fild F\$ebx | fstp R\$TmpRotate.Blue    lea ebx D@TmpAngle | move D\$ebx D@Angle | fild F\$ebx | fmul R\$Degree_Radian | fstp R\$TmpAngle    R\$TmpRotateRatio = (1 - cos(R\$TmpAngle)) * R\$Float_OneThird    R\$RotationMatrix.Data0_0 = (cos(R\$TmpAngle) + R\$TmpRotateRatio); * R\$GrayRedFactor_Rec709 ; seting the gray factor keep luma while not touching saturtion    R\$RotationMatrix.Data0_1 = (R\$TmpRotateRatio - (R\$Float_SquareRoot_OneThird*sin(R\$TmpAngle))); * R\$GrayGreenFactor_Rec709    R\$RotationMatrix.Data0_2 = (R\$TmpRotateRatio + (R\$Float_SquareRoot_OneThird*sin(R\$TmpAngle))); * R\$GrayBlueFactor_Rec709    R\$RotationMatrix.Data1_0 = R\$RotationMatrix.Data0_2    R\$RotationMatrix.Data1_1 = R\$RotationMatrix.Data0_0    R\$RotationMatrix.Data1_2 = R\$RotationMatrix.Data0_1    R\$RotationMatrix.Data2_0 = R\$RotationMatrix.Data0_1    R\$RotationMatrix.Data2_1 = R\$RotationMatrix.Data0_2    R\$RotationMatrix.Data2_2 = R\$RotationMatrix.Data0_0    lea ebx D@TmpStorage    fld R\$TmpRotate.Red | fmul R\$RotationMatrix.Data0_0 | fld R\$TmpRotate.Green | fmul R\$RotationMatrix.Data0_1 | faddp ST1 ST0    fld R\$TmpRotate.Blue | fmul R\$RotationMatrix.Data0_2 | faddp ST1 ST0 | fistp F\$ebx | On D\$ebx <s 0, mov D\$ebx 0 | On D\$ebx > 255, mov D\$ebx 255 | mov eax D\$ebx | mov B\$esi+RGBTRIPLE.rgbtRedDis al    fld R\$TmpRotate.Red | fmul R\$RotationMatrix.Data1_0 | fld R\$TmpRotate.Green | fmul R\$RotationMatrix.Data1_1 | faddp ST1 ST0    fld R\$TmpRotate.Blue | fmul R\$RotationMatrix.Data1_2 | faddp ST1 ST0 | fistp F\$ebx | On D\$ebx <s 0, mov D\$ebx 0 | On D\$ebx > 255, mov D\$ebx 255 | mov eax D\$ebx | mov B\$esi+RGBTRIPLE.rgbtGreenDis al    fld R\$TmpRotate.Red | fmul R\$RotationMatrix.Data2_0 | fld R\$TmpRotate.Green | fmul R\$RotationMatrix.Data2_1 | faddp ST1 ST0    fld R\$TmpRotate.Blue | fmul R\$RotationMatrix.Data2_2 | faddp ST1 ST0 | fistp F\$ebx | On D\$ebx <s 0, mov D\$ebx 0 | On D\$ebx > 255, mov D\$ebx 255 | mov eax D\$ebx | mov B\$esi+RGBTRIPLE.rgbtBlueDis alEndP`
Example of usage:
Code: [Select]
`[hBitsInMemory: D\$ 0]  ; a variable to store the pixel in an ARGB form         mov esi D\$hBitsInMemory         call RGBRotate esi, 260 ;<--- Angle always in degrees`
Btw: SOmeone knows how to achieve the hue angle using this sort of matrix ? For the reverted operation
Title: Re: RGBRotate
Post by: dedndave on June 01, 2014, 02:25:46 PM
Christian Graus wrote several articles
whether or not you find exactly what you're looking for, you'll enjoy his articles   :t

http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=6556 (http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=6556)

another one, i haven't had time to look at it closely

http://www.codeproject.com/Articles/426172/My-Photo-Editor (http://www.codeproject.com/Articles/426172/My-Photo-Editor)