Is there an API for getting the Windows 7 color of an icon? [duplicate]
Possible Duplicate:
Windows 7 Tasbar Icons Highlight Color
Windows 7 uses some algorithm to detect the average color of a pinned item in the Windows 7 taskbar in some way. Note how when you hover over an item, the glow color is the same as the icon.
Is there an API for getting that color?
Or is there an alternative?
[Edit: C# Code as requested]
Ok, well, in C# it actually could be done more-or-less like the link I gave, but there's really no reason to do all the masking and shifting, since you can already access a System.Drawing.Color
's ARGB values directly in C#. (Oh, by the way, I wasn't sure whether to average the Alpha value, I went with "yes".)
If your source data is in int
s instead Color
, you can always just convert the values with the function Color.FromArgb
with a single int
argument. (It supports also creating it from individual values, as shown in the example code's return
s.)
The LINQ version looks a loot easier to understand to me, but I gave the other one since it's basically a C# port of the original code I linked.
LINQ version:
public Color AverageColorsWithLINQ(Color[] ColorsToAverage)
{
// the LINQ way
int AlphaAverage = (int)ColorsToAverage.Average(c => c.A);
int RedAverage = (int)ColorsToAverage.Average(c => c.R);
int GreenAverage = (int)ColorsToAverage.Average(c => c.G);
int BlueAverage = (int)ColorsToAverage.Average(c => c.B);
return Color.FromArgb(
AlphaAverage, RedAverage, GreenAverage, BlueAverage
);
}
Loop, sum, and divide version:
public Color AverageColorsWithFor(Color[] ColorsToAverage)
{
int AlphaTotal = 0;
int RedTotal = 0;
int GreenTotal = 0;
int BlueTotal = 0;
foreach (Color AColor in ColorsToAverage)
{
AlphaTotal += AColor.A;
RedTotal += AColor.R;
GreenTotal += AColor.G;
BlueTotal += AColor.B;
}
double NumberOfColors = ColorsToAverage.Length;
int AlphaAverage = (int)(AlphaTotal / NumberOfColors);
int RedAverage = (int)(RedTotal / NumberOfColors);
int GreenAverage = (int)(GreenTotal / NumberOfColors);
int BlueAverage = (int)(BlueTotal / NumberOfColors);
return Color.FromArgb(
AlphaAverage, RedAverage, GreenAverage, BlueAverage
);
}
Well, I would check out How do I adjust the brightness of a color? which covers several different ways of doing it.
I'm not really sure what model Windows 7 is using to do it, but basically there are different models you can use to pick a color out of colorspace, and, in particular, HSL and HSV (http://en.wikipedia.org/wiki/HSL_and_HSV) can both be used to increase and decrease the perceived brightness of the color without altering it too much.
Upon re-reading your question I think I may have misunderstood. If you actually mean to average a block of colors, I would give this a shot: http://blog.soulwire.co.uk/code/actionscript-3/extract-average-colours-from-bitmapdata . It looks like it's doing it via RGB, though, and I'm not familiar enough to know whether that gives good results (for instance, it doesn't do a good job of raising or lowering brightness of a color to adjust the colors proportionally...)
So, if that doesn't give you good results, I would recommend trying converting all the colors to either HSV or HSL, averaging those values together instead, and then converting back to RGB.
精彩评论