Тонирование в сторону или вдали от оттенка определенным процентом

StackOverflow https://stackoverflow.com/questions/3097753

  •  29-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь подражать Эффект оттенка открытого XML. Что это делает, это изменить оттенок пикселей на изображение, сдвигая оттенок. Требуется 2 параметра: 1) hue (в градусах) и 2) amt (сумма, процент). Это №2, с которыми у меня проблемы. Спецификация гласит:

Оттенка: Сдвиги меняют значения цветовых значений либо в сторону или вдали от оттенка на указанную сумму.

  • атмосфера (Количество) - указывает, насколько изменение значения цвета.
  • оттенок (Hue) - указывает оттенок к которому к оттенку.

Не учитывая конструкцию XML, я могу эмулировать значения, которые имеют amt 100%. Так, например, если я хочу синий (оттенок: 240 °), я могу создать это ( Тонированный один). Вот пример:

Оригинал и Тонированный (Hue = 240, количество = 100%).
Original Modified

Это достигается просто путем установки оттенков до 240, сохраняя насыщенность и яркости одинаковую и преобразующую в RGB и пиксель.

Вот чего я не могу достичь:

Hue =240 (синий), Сумма = 30%, 50% и 80%, соответственно
30% 50% 80%

Опять же, спецификация для Amount говорит Указывает, насколько изменение значения цвета сдвинуто. Анкет Я пробовал всевозможные пути здесь, чтобы заставить это работать, но не могу (не могу (hue=hue*amount, originalhue * amount + hue, и т.д.)

Больше примеров: hue =120 (зеленый), Сумма = 30%, 50%, 80% и 100%, соответственно. То 100% один я могу получить.
30% 50% 80% 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


Итак, вопрос в том, кто знает, как это должно работать?

Примечание: это нет дубликат:

Это было полезно?

Решение

Я вполне уверен, что ваша проблема вытекает из того, как вы интерполируют углы. Вот функция интерполяции (написанная на 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) должен создать желаемый результат.

Редактировать: Насколько я понимаю, ваша цель состоит в том, чтобы повернуть первоначальный оттенок к определенному целевому оттенку некоторым данным количеством. Я уверен, что вы уже знакомы с этим, но ради иллюстрации, вот цветовое колесо.

Color Wheel
(источник: 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, хотя) - это может быть просто то, что вы ищете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top