在C#中旋转Hue

时间:2014-09-15 20:48:51

标签: c# gdi+

我希望复制找到here

的CSS3色调旋转行为

原始图片

original image

色调旋转180度的图像

image with hue rotated 180deg

我已经可以准确地将RGB值转换为HSL值并再次返回但是我不确定要应用于hue组件来复制输出的数学函数是什么。

2 个答案:

答案 0 :(得分:4)

的增添。

这很简单,只需在色调值上加180,然后确保它在360处包裹:

hue = (hue + 180) % 360;

答案 1 :(得分:1)

我想指出如何实际这样做。这是确切的问题,但没有好的答案。

鉴于GDI + Image,我想应用色调偏移并返回新图像。在实践中,它将返回一个新的Bitmap。我将使用C#style伪代码。

首先是克隆GDI +图像的基本内容(但还没有色调偏移):

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;
}

接下来的想法是,当我们使用Graphics.DrawImage方法时,我们可以提供ImageAttributes类。

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

其中一个属性可以是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);

魔法来自可以执行色调偏移的颜色矩阵。我创建了一个函数,可以返回执行所需色调偏移的 ColorMatrix

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;
}

所以我将创建一种新的功能,一种制作图像副本并对其应用ColorMatrix的功能:

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;
}

我们的色调偏移算法变为:

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

   return Multiply(cm);
}

我不知道色调偏移颜色矩阵来自哪里。它只存在于MSDN页面Hue rotation effect

enter image description here