Определить общую яркость изображения - PullRequest
8 голосов
/ 01 ноября 2011

Мне нужно наложить некоторые тексты на изображение; этот текст должен быть светлее или темнее в зависимости от общей яркости изображения. Как рассчитать общую (воспринимаемую) яркость изображения?

Нашел что-то интересное для одного пикселя: Формула для определения яркости цвета RGB

Ответы [ 2 ]

6 голосов
/ 02 ноября 2011

Решено мной:

    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;
    }
2 голосов
/ 01 ноября 2011

Я думаю, что все, что вы можете сделать, это измерить каждый пиксель на изображении и взять среднее значение. Если это слишком медленно для ваших целей, то я бы посоветовал взять равномерно распределенную выборку пикселей и использовать ее для вычисления среднего значения. Вы также можете ограничить пиксели областью, в которой вам нужно нарисовать текст.

Вы можете загрузить изображение как растровое изображение (http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx)) и использовать метод GetPixel для фактического получения значений цвета.

Как вы оцениваете яркость, зависит только от вас. Я хотел бы предложить более простой подход (скажем, просто принимая наивысшее значение цвета), на самом деле может быть лучше, поскольку некоторые пользователи будут воспринимать цвет иначе, чем человеческая норма (дальтонизм и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...