Как однозначно конвертировать цвет из RGB в HSL и обратно, получая один и тот же результат?
Казалось бы, элементарная задача, но на деле не все так просто. Есть формулы, по которым можно выполнять RGB/HSL конвертацию, и есть куча готовых библиотек. Но столкнулся с тем, что если из RGB получить HSL, а потом перевести обратно в RGB, то очень часто конечный результат отличается от начального. Т.е. берем, скажем, цвет #918151, конвертируем его в HSL, а потом преобразуем обратно в RGB и получаем #908050, это при расчетах с плавающей точкой с 15 значащими цифрами.
Оно, вроде, не критично, и глазу человеческому разница вряд ли будет заметна, но все ж задумался - а нет ли какого-то метода, который однозначно позволит конвертировать туда-обратно? Возможно, есть какие-то корректировочные таблицы, позволяющие компенсировать ошибки, накапливающиеся в вычислениях?
RabraBabr, вычисления обратимые, и это хорошо, но не хорошо то, что HSL считает совсем неверно. RGB(145, 129, 81) должно давать примерно HSL(45, 0.283.., 0.443..)
цветовые пространства RGB и HSL не совпадают, поэтому несоответствия неизбежны.
Например, полностью черному rgb(0, 0, 0) соответствует множество hsl(*, *, 0).
Хотя например, в этой работе предлагают точный целочисленный метод конвертации: Integer-based accurate conversion between RGB and ... (на англ.). Один из авторов — Владимир Чернов, выпускник Петербургского Политехнического университета.
Вообще, преобразования можно сделать обратимыми. Математические формулы однозначны.
Похоже там тупо где-то стоит округление вниз, ведь разница после преобразований по всем каналам - ровно 1. Может, это значение RGB в HSL на самом деле что-то вроде (15.01, 30.5, 49.9). Но в пиксели HSL в итоге запишутся целые числа (0-255). Из-за этого округления при обратном преобразовании получается не 0x91 а 0x90.6, что, опять же, округляется вниз.
Если так важна полная обратимость преобразований, попробуйте использовать 10-битные или 16-битные форматы пикселей (расширяя исходный 8-битный RGB нулями справа). Тогда эти округления не испортят важные вам 8 старших бит.
Дело в том что HSV - это полярная система коррдинат. Цилиндр по сути. И один из параметров цветового тона (угол вращения) может циклически повторяться неся одинаковый смысл. И может быть любым находясь в центре цилиндра.
Поэтому такая формула не будет никогда однозначной.