2011-11-01 54 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方法實際獲取顏色值。

您如何評估亮度完全取決於您。我會建議一個更簡單的方法(比如說取最高的顏色值)實際上可能會更好,因爲有些用戶會感覺顏色與人類規範不同(色盲等)。