16진수 색상 코드를 HSL로 변환하는 PHP 함수
웹 개발을 하다 보면 #FF5733 같은 16진수(Hex) 색상 값을 CSS에서 다루기 편한 HSL(색조·채도·명도) 형식으로 바꿔야 하는 경우가 종종 있습니다. 아래 PHP 함수를 사용하면 이러한 변환을 몇 줄의 코드로 손쉽게 처리할 수 있습니다.
변환 함수 소스 코드
아래 코드를 사용하면 16진수 색상 값을 HSL 값으로 변환할 수 있습니다.
function hex_To_Hsl($hex) {
// 16진수 문자열을 R, G, B 세 부분으로 분리
$hex_val = array($hex[0].$hex[1], $hex[2].$hex[3], $hex[4].$hex[5]);
// 각 채널을 0~1 범위의 실수로 정규화
$rgb_val = array_map(function($part) {
return hexdec($part) / 255;
}, $hex_val);
$max_val = max($rgb_val);
$min_val = min($rgb_val);
// 명도(L): 최댓값과 최솟값의 평균
$l = ($max_val + $min_val) / 2;
if ($max_val == $min_val) {
// 무채색이므로 색조와 채도는 0
$h = $s = 0;
} else {
$diff = $max_val - $min_val;
// 채도(S): 명도가 0.5 초과 여부에 따라 공식 선택
$s = $l > 0.5 ? $diff / (2 - $max_val - $min_val) : $diff / ($max_val + $min_val);
// 색조(H): 최댓값이 속한 채널에 따라 분기
switch($max_val) {
case $rgb_val[0]:
$h = ($rgb_val[1] - $rgb_val[2]) / $diff + ($rgb_val[1] < $rgb_val[2] ? 6 : 0);
break;
case $rgb_val[1]:
$h = ($rgb_val[2] - $rgb_val[0]) / $diff + 2;
break;
case $rgb_val[2]:
$h = ($rgb_val[0] - $rgb_val[1]) / $diff + 4;
break;
}
$h /= 6; // 0~1 범위로 정규화
}
return array($h, $s, $l); // [색조, 채도, 명도] 반환
}
동작 원리 살펴보기
이 함수의 핵심 로직은 다음 순서로 진행됩니다.
- 문자열 분리: 16진수 코드를 두 글자씩 잘라 R, G, B 세 채널로 나눕니다.
- 정규화:
hexdec()으로 각 채널을 10진수로 변환한 뒤 255로 나누어 0~1 범위의 값으로 맞춥니다. - 명도(L) 계산: RGB 값의 최댓값과 최솟값을 더한 후 2로 나눕니다.
- 채도(S) 계산: 명도가 0.5보다 큰지 여부에 따라 서로 다른 공식을 적용합니다.
- 색조(H) 계산: 최댓값이 어느 채널인지에 따라 switch 문으로 분기한 뒤 6으로 나누어 0~1 범위로 정규화합니다.
사용 예제
함수가 반환하는 값은 0~1 범위의 실수입니다. 일반적인 CSS 표기법으로 출력하려면 아래와 같이 변환하면 됩니다.
$color = '#FF5733';
list($h, $s, $l) = hex_To_Hsl($color);
printf('hsl(%d, %d%%, %d%%)', round($h * 360), round($s * 100), round($l * 100));
// 출력 결과: hsl(11, 100%, 60%)
참고 사항
- 입력값은 '#' 기호를 제외한 6자리 16진수 문자열이어야 합니다. '#'이 포함된 값은
substr($hex, 1)등으로 제거한 후 전달하세요. - 반환되는 색조는 0~1 값이며, 각도(0~360°)로 표현하려면 360을 곱하면 됩니다.
- 채도와 명도 역시 0~1 값이므로 백분율로 나타낼 때는 100을 곱합니다.
이 함수 하나만 있으면 테마 커스터마이징이나 디자인 시스템 구축 시 색상 조작 작업을 훨씬 간편하게 처리할 수 있습니다.