确定图像整体亮度
本文关键字:亮度 图像 | 更新日期: 2023-09-27 18:12:52
我需要在图片上叠加一些文字;此文本应根据图像的整体亮度而变浅或变暗。如何计算图像的整体(感知)亮度?
发现了一些有趣的单像素:RGB颜色亮度确定公式
由我解决:
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.299*R^2 + 0.587*G^2 + 0.114*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;
}
我认为你所能做的就是测量图像中的每个像素并取平均值。如果这对你的目的来说太慢了,那么我建议取一个均匀分布的像素样本,并用它来计算平均值。您还可以将像素限制在需要绘制文本的区域。
您可以将图像加载为位图(http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx),并使用GetPixel方法实际获取颜色值。
你如何评估亮度完全取决于你。我建议采用一种更简单的方法(比如只取最高的颜色值)实际上可能会更好,因为一些用户对颜色的感知与人类标准(色盲等)不同。