2016-10-11 8 views
2

私はc#を使用して画像の明るさを下げる必要があります。いくつかの分析の後、私は、各ピクセルカラーRGB値を調整することによって画像の明るさを減らす1つの解決策を見つけました。下からのコードを見つけてください:特定の色の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); 
      } 
     } 

方法:

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

関連する問題