2010-02-27 55 views
5

我試圖寫一個函數,可以讓我的紅移或同時保持圖像的整體亮度藍移位圖。基本上,完全紅移的位圖將具有與原始相同的亮度,但是會被徹底地重新着色(即,對於所有像素,G和B值將是相等的)。藍色相同(但R和G相等)。頻譜搬移的程度需要從預先0到1更改位圖的色調,同時保持整體亮度

由於變化。

+1

會改變顏色空間,HSV,然後轉移色相你在找什麼? – 2010-02-27 15:45:18

+0

單純皰疹病毒會有點工作,但不完全一樣。 – MusiGenesis 2010-02-27 15:58:10

+1

聽起來像你想要的是一個特定顏色的「灰度」圖像,這是正確的嗎? – 2010-02-27 21:14:15

回答

4

這裏是我一直在尋找(蹩腳JPEG,對不起)效果:

alt text http://www.freeimagehosting.net/uploads/d15ff241ca.jpg

在中間的圖像是原始的,並且側圖像是完全紅移,部分紅 - 分別移位,部分藍移和完全藍移。

這裏是產生這種效果的功能:

public void RedBlueShift(Bitmap bmp, double factor) 
{ 
    byte R = 0; 
    byte G = 0; 
    byte B = 0; 
    byte Rmax = 0; 
    byte Gmax = 0; 
    byte Bmax = 0; 
    double avg = 0; 
    double normal = 0; 
    if (factor > 1) 
    { 
     factor = 1; 
    } 
    else if (factor < -1) 
    { 
     factor = -1; 
    } 
    for (int x = 0; x < bmp.Width; x++) 
    { 
     for (int y = 0; y < bmp.Height; y++) 
     { 
      Color color = bmp.GetPixel(x, y); 
      R = color.R; 
      G = color.G; 
      B = color.B; 
      avg = (double)(R + G + B)/3; 
      normal = avg/255.0; // to preserve overall intensity 
      if (factor < 0) // red-tinted: 
      { 
       if (normal < .5) 
       { 
        Rmax = (byte)((normal/.5) * 255); 
        Gmax = 0; 
        Bmax = 0; 
       } 
       else 
       { 
        Rmax = 255; 
        Gmax = (byte)(((normal - .5) * 2) * 255); 
        Bmax = Gmax; 
       } 
       R = (byte)((double)R - ((double)(R - Rmax) * -factor)); 
       G = (byte)((double)G - ((double)(G - Gmax) * -factor)); 
       B = (byte)((double)B - ((double)(B - Bmax) * -factor)); 
      } 
      else if (factor > 0) // blue-tinted: 
      { 
       if (normal < .5) 
       { 
        Rmax = 0; 
        Gmax = 0; 
        Bmax = (byte)((normal/.5) * 255); 
       } 
       else 
       { 
        Rmax = (byte)(((normal - .5) * 2) * 255); 
        Gmax = Rmax; 
        Bmax = 255; 
       } 
       R = (byte)((double)R - ((double)(R - Rmax) * factor)); 
       G = (byte)((double)G - ((double)(G - Gmax) * factor)); 
       B = (byte)((double)B - ((double)(B - Bmax) * factor)); 
      } 
      color = Color.FromArgb(R, G, B); 
      bmp.SetPixel(x, y, color); 
     } 
    } 
} 
+0

咦?爲什麼有人會對此答案投下贊成票? – MusiGenesis 2010-06-12 01:56:17

+0

我可以想象這個代碼非常慢,因爲它使用每像素操作。 Hans Passant建議,我會研究ColorMatrix類。 – 2011-06-13 14:02:08

+0

@Will Kru:是的,由於'GetPixel'和'SetPixel',我發佈的代碼會超級慢。但是,ColorMatrix不適合我,因爲我的「位圖」並不是真正的.NET位圖 - 它們是2D「int」數組。我包含的函數使用.NET位圖和GetPixel/SetPixel,以便其他人更有用。 – MusiGenesis 2011-06-13 19:33:27

3

你會使用ColorMatrix類。在this project有一個很好的教程。

相關問題