Rotate Hue in C#

匿名 (未验证) 提交于 2019-12-03 08:51:18

问题:

I'm looking to replicate the CSS3 hue rotation behaviour found here

original image

image with hue rotated 180deg

I can already accurately convert an RGB value to a HSL value and back again but I'm not sure what the mathematical function to apply to the hue component to replicate the output is.

回答1:

Addition.

It's that simple, just add 180 to the hue value, then make sure that it wraps around at 360:

hue = (hue + 180) % 360; 


回答2:

I wanted to point out how to actually do this. This was the exact question, but no good answer.

Given a GDI+ Image, i want to apply a hue shift and return a new image. In practice it will return a new Bitmap. I'll use C# style pseudo-code.

First is the basic guts to clone a GDI+ image (but without the hue shift yet):

Bitmap CloneImage(Image sourceImage, Single hueShiftAngleDegrees) {    Int32 width  = sourceImage.GetWidth();    Int32 height = sourceImage.Getheight();     //Create destination bitmap    Bitmap bmpDest = new Bitmap(width, height, PixelFormat32bppARGB);     //Create a Graphics that will draw onto our destination bitmap    Graphics g = new Graphics(destinationBitmap);     //Draw the source image into the destination    g.DrawImage(sourceImage, MakeRect(0, 0, width, height),           0, 0, width, height, UnitPixel);     return bmpDest; } 

Next is the idea that when we use the Graphics.DrawImage method, we can supply an ImageAttributes class.

ImageAttributes attributes = new ImageAttributes(); g.DrawImage(sourceImage, MakeRect(0, 0, width, height),        0, 0, width, height, UnitPixel, attributes); 

One of these attributes can be a 5x5 ColorMatrix:

ColorMatrix cm = (    ( rr, gr, br, ar, 0 ),    ( rg, gg, bg, ag, 0 ),    ( rb, gb, bb, ab, 0 ),    ( ra, ga, ba, aa, 0 ),    ( r1, g1, b1, a1, 1 ) );  ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(cm); g.DrawImage(sourceImage, MakeRect(0, 0, width, height),        0, 0, width, height, UnitPixel, attributes); 

The magic comes from the color matrix that can perform a hue shift. I create a function that can return the ColorMatrix that performs the desired hue shift:

ColorMatrix GetHueShiftColorMax(Single hueShiftDegrees) {     /* Return the matrix          A00  A01  A02  0  0         A10  A11  A12  0  0         A20  A21  A22  0  0           0    0    0  1  0           0    0    0  0  1     */     Single theta = hueShiftDegrees/360 * 2*pi; //Degrees --> Radians     Single c = cos(theta);     Single s = sin(theta);      Single A00 = 0.213 + 0.787*c - 0.213*s;     Single A01 = 0.213 - 0.213*c + 0.413*s;     Single A02 = 0.213 - 0.213*c - 0.787*s;      Single A10 = 0.715 - 0.715*c - 0.715*s;     Single A11 = 0.715 + 0.285*c + 0.140*s;     Single A12 = 0.715 - 0.715*c + 0.715*s;      Single A20 = 0.072 - 0.072*c + 0.928*s;     Single A21 = 0.072 - 0.072*c - 0.283*s;     Single A22 = 0.072 + 0.928*c + 0.072*s;      ColorMatrix cm = new ColorMatrix(           ( A00, A01, A02,  0,  0 ),           ( A10, A11, A12,  0,  0 ),           ( A20, A21, A22,  0,  0 ),           (   0,   0,   0,  0,  0 ),           (   0,   0,   0,  0,  1 )     )      return cm; } 

So i'll create a new kind of function, one that makes a copy of an image and applies a ColorMatrix to it:

Bitmap Multiply(Image sourceImage, ColorMatrix cm) {    Int32 width  = sourceImage.GetWidth();    Int32 height = sourceImage.Getheight();     //Create destination bitmap    Bitmap bmpDest = new Bitmap(width, height, PixelFormat32bppARGB);     //Create a Graphics that will draw onto our destination bitmap    Graphics g = new Graphics(destinationBitmap);     //Draw the source image into the destination    ImageAttributes attributes = new ImageAttributes();    attributes.SetColorMatrix(cm);    g.DrawImage(sourceImage, MakeRect(0, 0, width, height),           0, 0, width, height, UnitPixel, attributes);     return bmpDest; } 

And our hue shift algorithm becomes:

Bitmap ApplyHueShift(Image sourceImage, Single hueShiftAngleDegrees) {    ColorMatrix cm = GetHueShiftColorMatrix(hueShiftAngleDegrees);     return Multiply(cm); } 

I have no idea where the hue shift color matrix comes from. It just exists on MSDN page Hue rotation effect:



文章来源: Rotate Hue in C#
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!