2016-10-11 129 views
2

我需要使用c#降低圖片的亮度。經過一些分析,我發現了一種解決方案,通過調整其每個像素顏色的RGB值來降低圖像的亮度。請從下面找到代碼:如何降低圖像亮度?

 Bitmap bmp = new Bitmap(Picture); 
     Reduce the picture color brightness 
     for (int i = 0; i < bmp.Width; i++) 
     { 
      for (int j = 0; j < bmp.Height; j++) 
      { 
       Color color = bmp.GetPixel(i, j); 
       color = ChangeColorBrightness(color, 0.80f); 
       bmp.SetPixel(i, j, color); 
      } 
     } 

方法,以減少特定顏色的RGB值:

private Color ChangeColorBrightness(Color color, float correctionFactor) 
    { 
     float red = (float)color.R; 
     float green = (float)color.G; 
     float blue = (float)color.B; 

     if (correctionFactor < 0) 
     { 
      correctionFactor = 1 + correctionFactor; 
      red *= correctionFactor; 
      green *= correctionFactor; 
      blue *= correctionFactor; 
     } 
     else 
     { 
      red = (255 - red) * correctionFactor + red; 
      green = (255 - green) * correctionFactor + green; 
      blue = (255 - blue) * correctionFactor + blue; 
     } 

     return Color.FromArgb(color.A, (int)red, (int)green, (int)blue); 
    } 

此代碼對我的要求,工作正常,但它會花費這樣的時間量當我執行大量寬度和高度較大的圖像。 有沒有其他的可能性來達到這個要求?

+1

而不是設置每個像素,再畫上一個新的你需要調整圖像。 [本答案](http://stackoverflow.com/a/15408608/2009)顯示瞭如何調整一次拍攝中的亮度,對比度和伽馬值。 – hometoast

+0

感謝您的建議。但我不喜歡在我的實現中使用Graphics對象。所以我忽略了使用顏色矩陣的方式。 – Vijay

回答

1

.GetPixel().SetPixel()是昂貴的 - 這裏是一個更快appraoch

public static Bitmap ChangeColorBrightness(Bitmap bmp, float correctionFactor) 
{ 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); 
    IntPtr ptr = bmpData.Scan0; 
    int bytes = Math.Abs(bmpData.Stride) * bmp.Height; 
    byte[] rgbValues = new byte[bytes]; 
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); 
    float correctionFactortemp = correctionFactor; 
    if (correctionFactor < 0) 
    { 
     correctionFactortemp = 1 + correctionFactor; 
    } 
    for (int counter = 1; counter < rgbValues.Length; counter ++) 
    { 
     float color = (float)rgbValues[counter]; 
     if (correctionFactor < 0) 
     { 
      color *= (int)correctionFactortemp; 
     } 
     else 
     { 
      color = (255 - color) * correctionFactor + color;     
     } 
     rgbValues[counter] = (byte)color;   
    } 
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); 
    bmp.UnlockBits(bmpData); 
    return bmp; 
} 
+0

我不喜歡在我的實現中使用圖形對象。沒有圖形對象有沒有可能? – Vijay

+0

@VijayR,就像你問的那樣:「這樣做的最快方法是什麼,但不要告訴我最快速的方法」 – hometoast

+0

推薦的方法是使用彩色矩陣。使用Winforms圖形通常意味着一個Graphics對象。不喜歡這是不合理的。在這個解決方案中,儘管使用Graphics對象是完全不必要的,並且什麼也不做。 – TaW