2010-10-01 185 views
0

我有一个图像,我想修改特定图像的色调到特定的值。 我知道rgb到hsl和hsl到rgb的转换数学公式,但是我不能把这个东西变成c#。C#中的图像色调修改#

以下是伪:

for(x=0;x<image_width;x++) 
{ 
    for(y=0;y<image_height;y++) 
    { 
    Color oldColor=GetColorFromPixel(x,y); 
    Color newColor=ModifyHue(oldColor); 
    SetColorPixel(x,y,newColor);  
    } 
} 

感谢

+0

如果你想让C#中的算法看看[this](http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm)。检查这是否与[wiki说](http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB)匹配... – tom3k 2010-10-01 08:31:32

回答

2

如果你只是想尝试或性能不是关键的,easist方式是使用Bitmap.GetPixelBitmap.SetPixel方法:

var bm = new Bitmap(filename); 
for(int x=0;x<bm.Width;x++) 
{ 
    for(y=0;y<bm.Height;y++) 
    { 
    Color oldColor=bm.GetPixel(x,y); 
    Color newColor=ModifyHue(oldColor); 
    bm.SetPixel(x,y,newColor);  
    } 
} 

如果你想要更高性能的操作,你应该看看Bitmap.LockBits方法,它修复了我的整个位图mory的位置,并让你直接修改这个内存。

5

由于这样的事实,即Color结构已经拥有了GetHue()GetSaturation()GetBrightness()这将是很好的构建也从这些值的颜色。所以我在网络上的某个地方发现了下面的代码(目前无法再找到它,但是它来自微软的一个人的博客,并且他还通过了所有KnownColor的测试)。

/// <summary> 
/// Creates a Color from alpha, hue, saturation and brightness. 
/// </summary> 
/// <param name="alpha">The alpha channel value.</param> 
/// <param name="hue">The hue value.</param> 
/// <param name="saturation">The saturation value.</param> 
/// <param name="brightness">The brightness value.</param> 
/// <returns>A Color with the given values.</returns> 
public static Color FromAhsb(int alpha, float hue, float saturation, float brightness) 
{ 

    if (0 > alpha || 255 < alpha) 
    { 
     throw new ArgumentOutOfRangeException("alpha", alpha, 
      "Value must be within a range of 0 - 255."); 
    } 
    if (0f > hue || 360f < hue) 
    { 
     throw new ArgumentOutOfRangeException("hue", hue, 
      "Value must be within a range of 0 - 360."); 
    } 
    if (0f > saturation || 1f < saturation) 
    { 
     throw new ArgumentOutOfRangeException("saturation", saturation, 
      "Value must be within a range of 0 - 1."); 
    } 
    if (0f > brightness || 1f < brightness) 
    { 
     throw new ArgumentOutOfRangeException("brightness", brightness, 
      "Value must be within a range of 0 - 1."); 
    } 

    if (0 == saturation) 
    { 
     return Color.FromArgb(alpha, Convert.ToInt32(brightness * 255), 
      Convert.ToInt32(brightness * 255), Convert.ToInt32(brightness * 255)); 
    } 

    float fMax, fMid, fMin; 
    int iSextant, iMax, iMid, iMin; 

    if (0.5 < brightness) 
    { 
     fMax = brightness - (brightness * saturation) + saturation; 
     fMin = brightness + (brightness * saturation) - saturation; 
    } 
    else 
    { 
     fMax = brightness + (brightness * saturation); 
     fMin = brightness - (brightness * saturation); 
    } 

    iSextant = (int)Math.Floor(hue/60f); 
    if (300f <= hue) 
    { 
     hue -= 360f; 
    } 
    hue /= 60f; 
    hue -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f)/2f); 
    if (0 == iSextant % 2) 
    { 
     fMid = hue * (fMax - fMin) + fMin; 
    } 
    else 
    { 
     fMid = fMin - hue * (fMax - fMin); 
    } 

    iMax = Convert.ToInt32(fMax * 255); 
    iMid = Convert.ToInt32(fMid * 255); 
    iMin = Convert.ToInt32(fMin * 255); 

    switch (iSextant) 
    { 
     case 1: 
      return Color.FromArgb(alpha, iMid, iMax, iMin); 
     case 2: 
      return Color.FromArgb(alpha, iMin, iMax, iMid); 
     case 3: 
      return Color.FromArgb(alpha, iMin, iMid, iMax); 
     case 4: 
      return Color.FromArgb(alpha, iMid, iMin, iMax); 
     case 5: 
      return Color.FromArgb(alpha, iMax, iMin, iMid); 
     default: 
      return Color.FromArgb(alpha, iMax, iMid, iMin); 
    } 
} 

有了这个功能,你可以在HSB(或HSV)色彩呈现的HSL演示文稿中的内工作。有关其差异的更多信息,请参阅this wikipedia article

+0

谢谢。我会在这方面进行锻炼。 – 2010-10-01 10:09:44