Я предполагаю, что независимо от того, какое отображение вы в конечном итоге используете, вы хотите отобразить черный на черный, белый на белый и серый на серый.
Аддитивное отображение
H '= H + (H target - H base )
(с циклическим изменением), которое вы используете для оттенка, действительно, вероятно, хорошо.Для насыщения необходимость сохранения значений серого предполагает мультипликативное отображение
S '= S * (S target / S base ),
со значениями, превышающими 100% обрезания насыщенности.Однако для легкости линейная карта просто не собирается этого делать, так как вы хотите зафиксировать как 0%, так и 100% легкость при настройке промежуточных значений.Вместо этого естественным выбором может быть карта типа gamma , т.е.
L '= pow (L, log (L target ) / log (L) base )) = exp (log (L) * log (L target ) / log (L base )).
где значения яркости масштабируются от 0 до 1. (Примечание: чтобы эффективно рассчитать эту карту для большого количества пикселей, вы, вероятно, захотите предварительно рассчитать таблицу поиска, скажем, из 256 записей.)
КонечноЕсть множество других карт, которые вы можете использовать, но я бы начал с них и посмотрел, дают ли они достаточно хорошие результаты.Обратите внимание, что, в конечном счете, качество ваших результатов также может быть ограничено воспринимаемой неоднородностью цветового пространства HSL;подробности см. на этой странице Википедии .