hcl2rgb.m 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. function rgb = hcl2rgb(h, c, l)
  2. %HCL2RGB Convert a HCL (i.e., CIELUV) color space value to one
  3. % in sRGB space.
  4. % RGB = HCL2RGB(H, C, L) will convert the color (H, C, L) in
  5. % HCL color space to RGB = [R, G, B] in sRGB color space.
  6. % Values that lie outside sRGB space will be silently corrected.
  7. % Code written by Nicholas J. Hughes, 2014, released under the following
  8. % licence.
  9. %
  10. % The MIT License (MIT)
  11. %
  12. % Copyright (c) 2014 Nicholas J. Hughes
  13. %
  14. % Permission is hereby granted, free of charge, to any person obtaining a copy
  15. % of this software and associated documentation files (the "Software"), to deal
  16. % in the Software without restriction, including without limitation the rights
  17. % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. % copies of the Software, and to permit persons to whom the Software is
  19. % furnished to do so, subject to the following conditions:
  20. %
  21. % The above copyright notice and this permission notice shall be included in
  22. % all copies or substantial portions of the Software.
  23. %
  24. % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. % THE SOFTWARE.
  31. % D65 White Point
  32. WHITE_Y = 100.000;
  33. WHITE_u = 0.1978398;
  34. WHITE_v = 0.4683363;
  35. if l < 0 || l > WHITE_Y || c < 0
  36. error('Invalid CIE-HCL color.');
  37. end
  38. % First convert to CIELUV (just a polar to Cartesian coordinate transformation)
  39. L = l;
  40. U = c * cosd(h);
  41. V = c * sind(h);
  42. % Now convert to CIEXYZ
  43. if L <= 0 && U == 0 && V == 0
  44. X = 0;
  45. Y = 0;
  46. Z = 0;
  47. else
  48. Y = WHITE_Y;
  49. if L > 7.999592
  50. Y = Y*((L + 16)/116)^3;
  51. else
  52. Y = Y*L/903.3;
  53. end
  54. u = U/(13*L) + WHITE_u;
  55. v = V/(13*L) + WHITE_v;
  56. X = (9.0*Y*u)/(4*v);
  57. Z = -X/3 - 5*Y + 3*Y/v;
  58. end
  59. % Now convert to sRGB
  60. r = gamma_correct((3.240479*X - 1.537150*Y - 0.498535*Z)/WHITE_Y);
  61. g = gamma_correct((-0.969256*X + 1.875992*Y + 0.041556*Z)/WHITE_Y);
  62. b = gamma_correct((0.055648*X - 0.204043*Y + 1.057311*Z)/WHITE_Y);
  63. % Round to integers and correct
  64. r = round(255 * r);
  65. g = round(255 * g);
  66. b = round(255 * b);
  67. r(r > 255) = 255;
  68. r(r < 0) = 0;
  69. g(g > 255) = 255;
  70. g(g < 0) = 0;
  71. b(b > 255) = 255;
  72. b(b < 0) = 0;
  73. rgb = [r, g, b];
  74. function u = gamma_correct(u)
  75. % Standard CRT Gamma
  76. GAMMA = 2.4;
  77. if u > 0.00304
  78. u = 1.055*u^(1/GAMMA) - 0.055;
  79. else
  80. u = 12.92*u;
  81. end