2011-11-01 2 views

答えて

5

は私が解決しよう:それを唱える

public static double CalculateAverageLightness(Bitmap bm) 
    { 
     double lum = 0; 
     var tmpBmp = new Bitmap(bm); 
     var width = bm.Width; 
     var height = bm.Height; 
     var bppModifier = bm.PixelFormat == PixelFormat.Format24bppRgb ? 3 : 4; 

     var srcData = tmpBmp.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, bm.PixelFormat); 
     var stride = srcData.Stride; 
     var scan0 = srcData.Scan0; 

     //Luminance (standard, objective): (0.2126*R) + (0.7152*G) + (0.0722*B) 
     //Luminance (perceived option 1): (0.299*R + 0.587*G + 0.114*B) 
     //Luminance (perceived option 2, slower to calculate): sqrt(0.241*R^2 + 0.691*G^2 + 0.068*B^2) 

     unsafe 
     { 
      byte* p = (byte*)(void*)scan0; 

      for (int y = 0; y < height; y++) 
      { 
       for (int x = 0; x < width; x++) 
       { 
        int idx = (y * stride) + x * bppModifier; 
        lum += (0.299*p[idx + 2] + 0.587*p[idx + 1] + 0.114*p[idx]); 
       } 
      } 
     } 

     tmpBmp.UnlockBits(srcData); 
     tmpBmp.Dispose(); 
     var avgLum = lum/(width * height); 


     return avgLum/255.0; 
    } 
+0

なぜ-1票を、?コードは正常に動作します! –

+0

'tmpBmp'を作成し、ビットを直接ロックするために' bm'を使わないのはなぜですか? – sergtk

+0

最後に平均を255で割りますか? @ʞᴉɯ – TheCoolFrood

2

私はあなたがすることができるすべては、画像内のすべてのピクセルを測定し、平均値を取るだと思う:単一のピクセルのための何か面白いものを見つけ

。それがあなたの目的には遅すぎる場合は、均等に分布したピクセルサンプルを取って平均を計算することをお勧めします。また、テキストを描画する必要がある領域にピクセルを制限することもできます。

イメージをビットマップ(http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx)として読み込み、GetPixelメソッドを使用して実際に色の値を取得することができます。

どのように明るさを評価するかは、あなた次第です。私はいくつかのユーザーが人間の基準(色盲など)と違った色を感じるので、より簡単なアプローチ(最高の色彩値をとること)が実際にはより良いかもしれないことを示唆しています。

関連する問題