20

This has intrigued me for quite some time.

Does anyone know the algorithm Windows 7 Aero uses to determine the colour to use as the hot-tracking hover highlight on taskbar buttons for currently-running apps?

Windows 7 taskbar hover colours

It is definitely based on the icon of the app, but I can't see a specific pattern of where it's getting the colour value from.

It doesn't seem to be any of the following:

  1. An average colour value from the entire icon, otherwise you would get brown all the time with multi-coloured icons like Chrome.
  2. The colour used the most in the image, otherwise you'd get yellow for the SQL Server Management Studio icon (6th from left). Also, the Chrome icon used red, green and yellow in equal measure.
  3. A colour located at certain pixel coordinates within the icon, because Chrome is red - indicating the top of the icon - and Notepad++ (2nd from right) is green - indicating the bottom of the icon.

I asked this question on ux.stackoverflow.com and it got closed as off-topic, but someone answered with the following:


As described by Raymond Chen in this MSDN blog article:

Some people ask how it's done. It's really nothing special. The code just looks for the predominant color in the icon. (And, since visual designers are sticklers for this sort of thing, black, white, and shades of gray are not considered "colors" for the purpose of this calculation.)


However I wasn't really satisfied with that answer because it doesn't explain how the "predominant" colour is calculated. Surely on the SQL Management Studio icon, the predominant colour, to my eyes at least, is yellow. Yet the highlight is green. I want to know, specifically, what the algorithm is.

  • An average colour value from the entire icon, otherwise you would get brown all the time. That doesn’t make sense. For example, how would the Skype, command-prompt, or µTorrent icons average out to brown? ಠ_ఠ (The last time I reverse-engineered one of Windows’ color-calculation algorithms, it took several years of on and off attention and a lot of different kinds of work to finally figure it out. It looks like I may end up hacking this one at some point.) – Synetech Jun 2 '14 at 18:00
  • @Synetech you're right - I was just thinking about the wide array of icons available and lots of them that contain multiple colours. For example the Chrome icon or the IIS icon contains red, green yellow & blue and green, yellow & blue respectively. I lazily figured these would average out to a murky brown colour, but you're right that it doesn't apply to lots of more-or-less monochrome icons. – theyetiman Jun 3 '14 at 8:37
  • The ONT post has a comment which links to a question about Chrome’s version of this and the linked page explains it by examining the Chrome source-code. The explanation (for that at least) isn’t exactly a simple algorithm. – Synetech Jun 9 '14 at 21:39
  • @Synetech nice find - now we're getting somewhere. This is along the lines of what I was looking for. Now, if only we could get the Win7 source code... ;) – theyetiman Jun 10 '14 at 9:15
  • I'm guessing but, all pixels are in 3-dimensional space (1 value for each color). Divide them in groups/cubes of for example 10x10x10 , so the color RGB(12,56,97) get's in the group/cube (10-20,50-60,90-100). When dividing the pixels over these groups you keep track of which one is the largest. Finally you determine the predominant color by averaging the group with the most pixels. The size of groups is then a trade of in performance/accuracy. – mxt3 Sep 17 '14 at 10:44
14

From Welcome to the Windows 7 Desktop at exactly 35 minutes in:

It's a normalized color histogram across 27 different buckets, and we extract blacks, whites, alpha channels, and grays, and use the most dominant RGBV [sic] value...

I'm fairly certain the speaker meant to say "RGB", since "RGBV" doesn't seem to be a thing. The "normalized" part doesn't really matter; it's effectively counting how many pixels fall into each "bucket." Each pixel, therefore, is put into one of the 27 buckets (arranged in a three-dimensional array; the cube root of 27 is 3) based on the position of each of its channels' value. Windows determines for each color channel whether that color's intensity is in the bottom, middle, or top chunk of the range. It would appear that the ranges are about 0-60, 60-200, and 200-255. Completely transparent pixels are not included at all.

Windows then finds which bucket has the most pixels, ignoring the black, white, and gray ones (the buckets where all three channels were in the same third of the range). That explains the SQL Server Management Studio icon - much of what appears yellow to us actually gets dumped in the "white" bucket and is ignored.

If there are no pixels in any of the acceptable buckets, the program gets a light blue overlay regardless of the system color scheme. (See the command prompt.) If a program has no icon, it gets a white/translucent overlay even though the Windows default icon would otherwise produce a blue or green overlay.

There is nothing to stop multiple programs from having the same highlight color. The newest Chrome icon, for instance, gets the same yellow as Windows 8's Explorer.

If there are ties, there is a predetermined order that does not depend on the order of the colors in the image. This is probably just a result of the way the maximum is found - buckets that are checked earlier will continue to be the max even if a later one ties. It appears that yellow is one of the first buckets checked.

Once the winning bucket is discovered, the highlight color seems to be set to a color somewhere in the middle of the bucket's range.

Test cases (numbers provided are RGB value):

bright yellow (255, 247, 209) → default highlight
red 47 (47, 0, 0) → default highlight
red 60 (60, 0, 0) → dark red
red 66 (66, 0, 0) → dark red
dark red (165, 0, 0) → red
gray 128 (128, 128, 128) → default highlight
halfs (0, 148, 255) and (255, 0, 0) → red
more halfs (0, 255, 0) and (255, 216, 0) with same area → yellow
same reversed same but flipped → yellow
white red 180 (255, 180, 180) → light red
white red 210 (255, 210, 210) → default highlight
quarters pure blue, pure yellow, pure red, and pure green with same area → yellow
white red 61 (255, 61, 61) → red
red 82 (82, 0, 0) → dark red

  • This is the most delish answer yet. Thank you. It explains everything I had trouble with and also goes into intense depth. Bravo. – theyetiman Feb 14 '16 at 1:58
  • @Ben N I know this looks like a dumb question, but still. Why 27 buckets? I know it's 3^3, and I guess the first 3 is the R, G and B colors, but what does the second 3 stand for? – aexl Mar 5 '16 at 20:11
  • @TheSexiestManinJamaica I think it's just arbitrary; maybe Microsoft liked the elegance of 3^3. It's a nice balance between there being very few possible colors (3^2 is only 9) and lots of possible colors (3^4 is 81). – Ben N Mar 5 '16 at 20:35
0

My guess would be that for each color, starting from the top, you get the R, G, and B values, and from them you take the highest and lowest of the three and compare them. The color with the biggest gap between the highest and lowest would be the brightest color in the image. Now in the case of, say, the Chrome icon, there might be several colors tied for biggest gap, but the red is on the top, so it's encountered first, and thus that's what dominates for that image. (I suppose you could test this by designing your own icon, like rotate the Chrome logo 120 degrees and see if the green or yellow dominates instead.)

0

From the way I understand it - The OS takes more than a few factors into account when determining the color.

  1. Has a color already been assigned by the OS to this application? If so, skip to 7.
  2. Is this color defined in the program code? If so, use the predefined color from the program. (Yes, there is a variable setting for windows programs that controls this, no, I do not know the exact variable name)
  3. if 1=false (Meaning no predefined color), define the dominant color of the icon used. (For this, the colors Black, white and grey are ignored)
  4. If 2 cannot define a single color that is used, and more dominant than the other colors used, define the average RBG value of the icon. If a defined color is achieved, use this. For the purpose of this, the colors White, Black, Grey and Brown are completely ignored.
  5. If 3 results in one of the blacklisted colors (Black white or grey), randomly assign a color that most closely represents the average RBG value, without infringing upon the blacklist colors.
  6. Upon successful assignment of the color is complete, store the color information in the registry for quicker color assignment later.
  7. If the color assigned matches a color already used by another application currently open, offset the color by a random hue amount within 15% of the assigned color.
  8. Display color.

This may very well be wrong, and is mostly speculation, but, this gives you a easy to understand method the OS could very well be using to determine the colors. It also explains how a program without a predefined color, and an icon using equal amounts of colors, isn't assigned white/brown/black, and why black, white and grey are never assigned. Also you should note, that programs that don't have an Icon (there are some still) show a transparent hot-tracking color, which simply causes the icon to be 'brighter' when hovered over.

  • There is not a way for applications to define their own color. There also doesn't seem to be any rule against two programs having the same color. Interesting ideas, though. – Ben N Feb 13 '16 at 19:06
-2

Here is some VB code that averages the RGB colours of an image:

Function AverageRGB(ByRef P As PictureBox) As Long

Dim Count As Long
Dim Red As Long
Dim Green As Long
Dim Blue As Long
Dim Hexed As String
Dim X As Long
Dim Y As Long
Count = 0


For X = 0 To P.Width Step P.Width \ 32


    For Y = 0 To P.Height Step P.Height \ 32
        Hexed = Right("00000" & Hex(P.Point(X, Y)), 6)
        Red = Red + CLng("&h" & Right(Hexed, 2))
        Green = Green + CLng("&h" & Mid(Hexed, 3, 2))
        Blue = Blue + CLng("&h" & Left(Hexed, 2))
        Count = Count + 1
    Next

Next

AverageRGB = RGB(Red \ Count, Green \ Count, Blue \ Count)
End Function

It's not really optimized for use in an OS, but it should give you a basic idea -Source

  • 3
    He already explained that it is not a simple/basic average. Run the Chrome icon through the code and you’ll see that for yourself. – Synetech Jun 2 '14 at 18:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.