Линейное преобразование RGB в / из HSL
Кто-нибудь знает способ получить HSL от цвета linearRGB (не цвета sRGB)? Я видел много преобразований sRGB<->HSL, но ничего для линейного RGB<->HSL. Не уверен, что это в принципе то же самое преобразование с незначительными изменениями, но я был бы признателен, если бы кто-то понял это.
Линейный RGB - это не то же самое, что линеаризация sRGB (который принимает [0,255] и делает его [0,1]). Линейное преобразование RGB из / в sRGB находится по адресу http://en.wikipedia.org/wiki/SRGB. В VBA это будет выражаться (принимая в линеаризованные значения sRGB [0,1]):
Public Function sRGB_to_linearRGB(value As Double)
If value < 0# Then
sRGB_to_linearRGB = 0#
Exit Function
End If
If value <= 0.04045 Then
sRGB_to_linearRGB = value / 12.92
Exit Function
End If
If value <= 1# Then
sRGB_to_linearRGB = ((value + 0.055) / 1.055) ^ 2.4
Exit Function
End If
sRGB_to_linearRGB = 1#
End Function
Public Function linearRGB_to_sRGB(value As Double)
If value < 0# Then
linearRGB_to_sRGB = 0#
Exit Function
End If
If value <= 0.0031308 Then
linearRGB_to_sRGB = value * 12.92
Exit Function
End If
If value < 1# Then
linearRGB_to_sRGB = 1.055 * (value ^ (1# / 2.4)) - 0.055
Exit Function
End If
linearRGB_to_sRGB = 1#
End Function
Я попытался отправить линейные значения RGB в стандартные процедуры RGB_to_HSL и вернуться из HSL_to_RGB, но это не работает. Возможно, потому что современные алгоритмы HSL<->RGB учитывают гамма-коррекцию, а линейный RGB не гамма-корректируется - я точно не знаю. Я почти не видел упоминаний о том, что это можно сделать, кроме двух:
- Ссылка на http://en.wikipedia.org/wiki/HSL_and_HSV(пронумерованный пункт 10).
- Ссылка на проект с открытым исходным кодом Grafx2 @ http://code.google.com/p/grafx2/issues/detail?id=63 в котором автор утверждает, что он выполнил линейное преобразование RGB <-> HSL, и предоставляет некоторый код C во вложении к его комментарию в файле.diff (который я действительно не могу прочитать:()
Мое намерение состоит в том, чтобы:
- отправить из sRGB (например,
FF99FF
(R=255, G=153, B=255
)) в линейный RGB (R=1.0, G=0.318546778125092, B=1.0
)- используя код выше (например, G=153 будет получен в линейном RGB из
sRGB_to_linearRGB(153 / 255)
)
- используя код выше (например, G=153 будет получен в линейном RGB из
- в HSL
- изменить / модулировать насыщенность на 350%
- отправить обратно из HSL->Linear
RGB->sRGB, результат будет
FF19FF
(R=255, G=25, B=255
).
Использование доступных функций из.NET, таких как .getHue
из System.Drawing.Color
не работает ни в одном пространстве sRGB с модуляцией выше 100% любого значения HSL, поэтому необходимо отправлять линейный RGB вместо sRGB.
4 ответа
Преобразование в линейный RGB не имеет особого смысла, поскольку HSL определяется в терминах значений, закодированных в гамма-диапазоне. Вместо этого, напишите свою собственную функцию, преобразуйте sRGB в HSL, смодулируйте насыщенность этими значениями (позволяя получить потенциально насыщенные значения вне пределов гаммы), а затем преобразуйте обратно в sRGB, ограничивая интенсивности, выходящие за пределы диапазона sRGB (или запрещая изменения насыщенности, которые не может быть закодирован в sRGB).
Исходя из вашего комментария здесь, ваша проблема не делает преобразование неправильно; Дело в том, что вы выполняете последовательные преобразования квантованных значений. Другими словами, вы берете результат sRGB=>RGB=>HSL=>HSL=>RGB=>sRGB и используете его в последующих цветовых операциях. Самый простой способ поддержания точности - всегда сохранять исходное значение RGB и накапливать изменения в пространстве HSL, которые вы хотите применить. Таким образом, вы всегда применяете операции пространства HSL к исходному цвету, и вам не нужно беспокоиться о повторной обработке квантованных значений.
Класс System.Windows.Media.Color позволяет вам получить или установить scRGB через свойства ScA,ScR,ScG,ScB или RGB через свойства A,R,G,B.
Таким образом, вы можете преобразовать RGB в HSL, манипулировать этим, затем преобразовать обратно в RGB и сохранить в экземпляре Color. Затем вы можете прочитать преобразованные свойства scRGB.
Не идеально, и может привести к потере информации. Но это вариант!
Это помогает? В этом вопросе есть много интересных ссылок, возможно, что-то, что работает и в вашем случае...