Как Windows 7 рассчитывает цвет, используемый для панели задач «отслеживание цвета»?

20

Это заинтриговало меня довольно давно.

Кто-нибудь знает алгоритм, который Windows 7 Aero использует для определения цвета, который будет использоваться в качестве выделения при наведении курсора на горячие кнопки на кнопках панели задач для работающих в данный момент приложений?

Windows 7 панель задач цвета при наведении

Это определенно основано на значке приложения, но я не могу видеть определенный образец того, откуда он получает значение цвета.

Похоже, что это не одно из следующих:

  1. Среднее значение цвета для всей иконки, в противном случае вы бы все время становились коричневыми с разноцветными значками, такими как Chrome.
  2. В изображении используется больше всего цвета, в противном случае вы получите желтый значок SQL Server Management Studio (6-й слева). Кроме того, значок Chrome использовал красный, зеленый и желтый в равной степени.
  3. Цвет, расположенный в определенных пиксельных координатах на значке, потому что Chrome красный - это указывает на верхнюю часть значка - а Notepad ++ (2-й справа) - зеленый - указывает на нижнюю часть значка.

Я задал этот вопрос на ux.stackoverflow.com, и он был закрыт как не по теме, но кто-то ответил со следующим:


Как описано Рэймондом Ченом в этой статье в блоге MSDN :

Некоторые люди спрашивают, как это делается. Это действительно ничего особенного. Код просто ищет преобладающий цвет в значке. (И, поскольку визуальные дизайнеры являются сторонниками такого рода вещей, черный, белый и оттенки серого не считаются «цветами» для целей этого расчета.)


Однако я не был действительно удовлетворен этим ответом, потому что он не объясняет, как рассчитывается «преобладающий» цвет. Конечно, на значке SQL Management Studio преобладающим цветом, по моему мнению, является желтый. Все же основной момент - зеленый. Я хочу знать, в частности, что это за алгоритм.

theyetiman
источник
An average colour value from the entire icon, otherwise you would get brown all the time.Это не имеет смысла. Например, как значки Skype , командной строки или µTorrent будут в среднем коричневыми? ಠ_ ఠ (В прошлый раз, когда я заново разработал один из алгоритмов вычисления цвета в Windows, потребовалось несколько лет внимания и много разных видов работы, чтобы наконец понять это. Похоже, что я могу в итоге взломать это один в какой-то момент.)
Synetech
@ Synetech, вы правы - я просто размышлял о множестве доступных значков и множестве из них, содержащих несколько цветов. Например, значок Chrome или значок IIS содержат красный, зеленый, желтый, синий и зеленый, желтый и синий соответственно. Я лениво полагал, что в среднем они получатся мутно-коричневого цвета, но вы правы, что это не относится ко многим более или менее монохромным иконкам.
theyetiman
В сообщении ONT есть комментарий, который ссылается на вопрос о версии Chrome, а на связанной странице это объясняется путем изучения исходного кода Chrome. Объяснение (по крайней мере для этого) не совсем простой алгоритм.
Synetech
@Synetech хорошая находка - теперь мы куда-то добираемся. Это в соответствии с тем, что я искал. Теперь, если бы мы только могли получить исходный код Win7 ...;)
sheetiman
Я предполагаю, но все пиксели находятся в трехмерном пространстве (1 значение для каждого цвета). Разделите их на группы / кубы, например, 10x10x10, чтобы цвет RGB (12,56,97) попал в группу / куб (10-20,50-60,90-100). При разделении пикселей на эти группы вы отслеживаете, какой из них самый большой. Наконец, вы определяете преобладающий цвет, усредняя группу с наибольшим количеством пикселей. Размер групп в таком случае зависит от эффективности / точности.
mxt3

Ответы:

14

От Добро пожаловать на рабочий стол Windows 7 ровно за 35 минут:

Это нормализованная цветовая гистограмма для 27 различных сегментов, и мы извлекаем черные, белые, альфа-каналы и серые цвета и используем наиболее доминирующее значение RGBV [sic] ...

Я вполне уверен, что спикер хотел сказать «RGB», поскольку «RGBV», кажется, не вещь. «Нормализованная» часть на самом деле не имеет значения; он эффективно подсчитывает, сколько пикселей попадает в каждое «ведро». Поэтому каждый пиксель помещается в одно из 27 сегментов (расположенных в трехмерном массиве; корень куба из 27 равен 3) в зависимости от положения каждого из его каналов. Windows определяет для каждого цветового канала, находится ли интенсивность этого цвета в нижней, средней или верхней части диапазона. Похоже, что диапазоны составляют около 0-60, 60-200 и 200-255. Полностью прозрачные пиксели вообще не включены.

Затем Windows находит, какой сегмент имеет наибольшее количество пикселей, игнорируя черный, белый и серый (сегменты, где все три канала находились в одной трети диапазона). Это объясняет значок SQL Server Management Studio - большая часть того, что нам кажется желтым, на самом деле сбрасывается в «белое» поле и игнорируется.

Если ни в одном из допустимых сегментов нет пикселей, программа получает светло-синее наложение независимо от цветовой схемы системы. (См. Командную строку.) Если у программы нет значка, она получает белое / полупрозрачное наложение, даже если значок Windows по умолчанию в противном случае приведет к наложению синего или зеленого цвета.

Ничто не мешает нескольким программам иметь одинаковый цвет подсветки. Например, новейшая иконка Chrome становится такой же желтой, как проводник Windows 8.

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

Как только выигрышное ведро обнаружено, цвет выделения, кажется, устанавливается на цвет где-то в середине диапазона ведра.

Тестовые случаи (предоставленные значения являются значениями RGB):

ярко-желтый(255, 247, 209) → выделение по умолчанию
красный 47(47, 0, 0) → выделение по умолчанию
красный 60(60, 0, 0) → темно-красный
красный 66(66, 0, 0) → темно-красный
темно-красный(165, 0, 0) → красный
серый 128( 128, 128, 128) → выделение по умолчанию
половинки(0, 148, 255) и (255, 0, 0) → красный
больше половинок(0, 255, 0) и (255, 216, 0) с той же областью → желтый
то же самое наобороттакой же, но перевернутый → желтый
белый красный 180(255, 180, 180) → светло-красный
белый красный 210(255, 210, 210) → выделение по умолчанию:
помещениечисто-синий, чисто-желтый, чисто-красный и чисто-зеленый с той же площадью → желтый
белый красный 61(255, 61, 61) → красный
красный 82(82, 0, 0) → темно-красный

Бен Н
источник
Это самый деликатный ответ. Спасибо. Это объясняет все, с чем у меня были проблемы, а также углубляется в глубину. Браво.
16:15
@ Бен Я знаю, что это выглядит глупо, но все же. Почему 27 ведер? Я знаю, что это 3 ^ 3, и я думаю, что первые 3 - это цвета R, G и B, но что означают вторые 3?
2016 г.
@TheSexiestManinJamaica Я думаю, это просто произвольно; возможно Microsoft понравилась элегантность 3 ^ 3. Это хороший баланс между очень малым количеством возможных цветов (3 ^ 2 - только 9) и множеством возможных цветов (3 ^ 4 - 81).
Бен Н
0

Я предполагаю, что для каждого цвета, начиная сверху, вы получаете значения R, G и B, а из них вы берете самое высокое и самое низкое из трех и сравниваете их. Цвет с наибольшим зазором между самым высоким и самым низким будет самым ярким цветом на изображении. Теперь в случае, скажем, значка Chrome, может быть несколько цветов, связанных для наибольшего промежутка, но красный сверху, поэтому он встречается первым, и поэтому это то, что доминирует для этого изображения. (Я полагаю, вы можете проверить это, разработав собственную иконку, например, повернуть логотип Chrome на 120 градусов и посмотреть, доминирует ли зеленый или желтый вместо этого.)

Даррел Хоффман
источник
0

Насколько я понимаю - ОС принимает во внимание более чем несколько факторов при определении цвета.

  1. Цвет уже был назначен ОС для этого приложения? Если это так, перейдите к 7.
  2. Этот цвет определен в коде программы? Если это так, используйте предопределенный цвет из программы. (Да, есть переменная настройка для программ Windows, которая контролирует это, нет, я не знаю точное имя переменной)
  3. если 1 = ложь (что означает отсутствие предопределенного цвета), определите основной цвет используемого значка. (Для этого цвета черный, белый и серый игнорируются)
  4. Если 2 не может определить один используемый цвет, который является более доминирующим, чем другие используемые цвета, определите среднее значение RBG значка. Если достигнут определенный цвет, используйте это. Для этого цвета Белый, Черный, Серый и Коричневый полностью игнорируются.
  5. Если 3 приводит к одному из цветов в черном списке (черный белый или серый), случайным образом назначьте цвет, который наиболее точно соответствует среднему значению RBG, не затрагивая цвета черного списка.
  6. После успешного назначения цвета сохраните информацию о цвете в реестре для более быстрого назначения цвета позже.
  7. Если назначенный цвет соответствует цвету, уже используемому другим открытым в данный момент приложением, сместите цвет на случайную величину оттенка в пределах 15% от назначенного цвета.
  8. Цвет дисплея.

Вполне возможно, что это неправильно, и в основном это спекуляция, но это дает вам простой для понимания метод, который ОС вполне может использовать для определения цветов. Также объясняется, как программе без предопределенного цвета и значку, использующему равное количество цветов, не назначается белый / коричневый / черный, и почему черный, белый и серый никогда не назначаются. Также вы должны отметить, что программы, у которых нет иконки (есть еще некоторые), показывают прозрачный цвет горячего отслеживания, который просто делает иконку «ярче» при наведении курсора.

Джош Рэймонд
источник
У приложений нет способа определить свой собственный цвет. Похоже, что нет никаких правил против двух программ, имеющих одинаковый цвет. Интересные идеи, хотя.
Бен Н
-2

Вот некоторый код VB, который усредняет цвета RGB изображения:

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

Он не оптимизирован для использования в ОС, но должен дать вам основную идею - Source


источник
3
Он уже объяснил, что это не простое / базовое среднее. Запустите значок Chrome через код, и вы сами это увидите.
Synetech