Determine image overall lightness

后端 未结 2 766
猫巷女王i
猫巷女王i 2021-02-09 01:50

I need to overlay some texts on an image; this text should be lighter or darker based on the overall image lightness. How to compute the overall (perceived) lightness of an imag

相关标签:
2条回答
  • 2021-02-09 02:10

    I think all you can do is measure every pixel in the image and take an average. If thats too slow for your purposes then I would suggest taking an evenly distributed sample of pixels and using that to calculate an average. You could also limit the pixels to the area where you need to draw the text.

    You can load the image as a Bitmap (http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx) and use the GetPixel method to actually get the colour values.

    How you assess the brightness is entirely up to you. I would suggest a simpler approach (say just taking the highest colour value) may actually be better as some users will perceive colour differently to the human norm (colour-blindness etc).

    0 讨论(0)
  • 2021-02-09 02:13

    Solved by me:

        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;
        }
    
    0 讨论(0)
提交回复
热议问题