Тонирование в сторону или вдали от оттенка определенным процентом
Вопрос
Я пытаюсь подражать Эффект оттенка открытого XML. Что это делает, это изменить оттенок пикселей на изображение, сдвигая оттенок. Требуется 2 параметра: 1) hue
(в градусах) и 2) amt
(сумма, процент). Это №2, с которыми у меня проблемы. Спецификация гласит:
Оттенка: Сдвиги меняют значения цветовых значений либо в сторону или вдали от оттенка на указанную сумму.
- атмосфера (Количество) - указывает, насколько изменение значения цвета.
- оттенок (Hue) - указывает оттенок к которому к оттенку.
Не учитывая конструкцию XML, я могу эмулировать значения, которые имеют amt
100%. Так, например, если я хочу синий (оттенок: 240 °), я могу создать это ( Тонированный один). Вот пример:
Оригинал и Тонированный (Hue = 240, количество = 100%).
Это достигается просто путем установки оттенков до 240, сохраняя насыщенность и яркости одинаковую и преобразующую в RGB и пиксель.
Вот чего я не могу достичь:
Hue =240 (синий), Сумма = 30%, 50% и 80%, соответственно
Опять же, спецификация для Amount
говорит Указывает, насколько изменение значения цвета сдвинуто. Анкет Я пробовал всевозможные пути здесь, чтобы заставить это работать, но не могу (не могу (hue=hue*amount
, originalhue * amount + hue
, и т.д.)
Больше примеров: hue =120 (зеленый), Сумма = 30%, 50%, 80% и 100%, соответственно. То 100% один я могу получить.
Вот некоторые значенные списки одного пикселя на картинках выше:
Pixel 159, 116 - Синие картинки
Сумма оттенка RGB | HSL Оригинал 244 196 10 | 48 0.92 0.5 Blue 240 30% 237 30 45 | 356 0.85 0.52 Blue 240 50% 245 9 156 | 323 0.93 0.5 Blue 240 80% 140 12 244 | 273 0.91 0.5 Blue 240 100% 12 12 244 | 240 0.91 0.5
Pixel 159, 116 - зеленые картинки
Сумма оттенка RGB | HSL Оригинал 244 196 10 | 48 0.92 0.5 Green 120 30% 211 237 30 | 68 0.85 0.52 Green 120 50% 159 237 30 | 83 0.85 0.52 Green 120 80% 81 237 29 | 105 0.85 0.52 Green 120 100% 29 237 29 | 120 0.85 0.52
Итак, вопрос в том, кто знает, как это должно работать?
Примечание: это нет дубликат:
- Изменение оттенка растрового изображения при сохранении общей яркости
- Поверните оттенок, используя ImageAttribute в C #
- ... или что -нибудь еще, что я мог найти, так что
Решение
Я вполне уверен, что ваша проблема вытекает из того, как вы интерполируют углы. Вот функция интерполяции (написанная на Python), которая должна сделать свое дело. Он основан на предложении из ветки форумов XNA Самая короткая 2 -я угловая интерполяция.
def wrap(value, lower, upper):
distance = upper - lower
return value - ((value-lower)//distance)*distance
def shortestangle(a,b):
angle = wrap(b-a, 0, 360)
if angle>=180: angle -= 360
return angle
def interpolate(a,b,amount):
return (a+shortestangle(a,b)*amount)%360
Теперь, interpolate(originalHue,hue,amount)
должен создать желаемый результат.
Редактировать: Насколько я понимаю, ваша цель состоит в том, чтобы повернуть первоначальный оттенок к определенному целевому оттенку некоторым данным количеством. Я уверен, что вы уже знакомы с этим, но ради иллюстрации, вот цветовое колесо.
(источник: SapdesignGuild.org)
Проблема в том, что смешивание (или интерполяции) два угла не тривиально, поэтому код как hue = ((hue - originalHue) * amount) + originalHue
не будет работать. Существует бесконечное количество способов, которыми вы можете перейти от одного угла на другой из-за обтекания при 360 °. Чтобы получить от 0 ° до 60 °, вы можете вращать на 60 ° против часовой стрелки, на 420 ° против часовой стрелки, на 300 ° по часовой стрелке и т. Д. Обычно самый короткий угол - это желаемый.
Например, рассмотрим шеи пингвинов: если ваш первоначальный оттенок составляет 30 ° (оранжевый), ваша цель составляет 240 ° (синий), а количество составляет 50%, вы получите следующие результаты:
//Linear Interpolation
(30° + (240° - 30°)*0.5) = 135° (green)
//"Shortest 2D Angle Interpolation"
(30° + shortestangle(30°,240°)*0.5) % 360 = (30° + (-150°)*0.5) % 360 = 315° (magenta)
Я предполагаю, что второй результат - тот, который вы ищете, но я могу ошибаться, и ошибка может быть где -то еще ...
Другие советы
Вы должны взглянуть на Tintparams В GDI + (не является частью .NET, хотя) - это может быть просто то, что вы ищете.