C# 确定图像的整体亮度

C# 确定图像的整体亮度,c#,.net,imaging,C#,.net,Imaging,我需要在图像上叠加一些文本;根据整体图像亮度,此文本应更亮或更暗。 如何计算图像的整体(感知)亮度 发现了单像素的有趣内容: 我想你所能做的就是测量图像中的每个像素并取平均值。如果这对于你来说太慢了,那么我建议你取一个均匀分布的像素样本,然后用它来计算平均值。您还可以将像素限制在需要绘制文本的区域 可以将图像作为位图加载(http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx)并使用GetPixel方法实际获取颜色值

我需要在图像上叠加一些文本;根据整体图像亮度,此文本应更亮或更暗。 如何计算图像的整体(感知)亮度

发现了单像素的有趣内容:
我想你所能做的就是测量图像中的每个像素并取平均值。如果这对于你来说太慢了,那么我建议你取一个均匀分布的像素样本,然后用它来计算平均值。您还可以将像素限制在需要绘制文本的区域

可以将图像作为位图加载(http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx)并使用GetPixel方法实际获取颜色值

如何评估亮度完全取决于您。我建议采用一种更简单的方法(比如只取最高的颜色值)可能会更好,因为一些用户会对颜色的感知与人类的正常情况不同(色盲等)。

我解决了:

    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;
    }
公共静态双计算亮度(位图bm)
{
双lum=0;
var tmpBmp=新位图(bm);
变量宽度=bm.宽度;
变量高度=bm.高度;
var bppModifier=bm.PixelFormat==PixelFormat.Format24bppRgb?3:4;
var srcData=tmpBmp.LockBits(新矩形(0,0,bm.Width,bm.Height),ImageLockMode.ReadOnly,bm.PixelFormat);
var stride=srcData.stride;
var scan0=srcData.scan0;
//亮度(标准、物镜):(0.2126*R)+(0.7152*G)+(0.0722*B)
//亮度(感知选项1):(0.299*R+0.587*G+0.114*B)
//亮度(感知选项2,计算速度较慢):sqrt(0.299*R^2+0.587*G^2+0.114*B^2)
不安全的
{
字节*p=(字节*)(空*)扫描0;
对于(int y=0;y
为什么需要创建
tmpBmp
,而不使用
bm
直接锁定其中的位?为什么要在末尾将平均值设为255@ʞᴉɯ@TheCoolFrood它将其标准化为0.0-1.0的范围。该值越高,图像的平均值越轻。