PHOTOSHOT / DEVELOPMENT JOURNAL
파랑만 바꿀 때
경계의 색은
얼마나 바뀔까
파랑을 선택했다고 파랑과 아닌 색을 칼같이 나누지는 않습니다. 중심에서 가까운 색은 충분히 바꾸고, 경계에 가까워질수록 적용량을 줄였습니다.


06편에서는 색을 고르는 범위와 조정량을 계산하는 부분을 나누어 봅니다. 화면의 파랑 선택이 코드의 중심각·폭·페더로 연결되는 과정입니다.
파랑 선택을 세 숫자로 저장하기
예제에서는 파랑 범위를 선택하고 색조 −45, 채도 −10, 명도 +12로 조절했습니다. 범위는 중심 240°, 폭 30°, 페더 30°입니다. 화면의 배경처럼 파란 계열이 다른 색으로 이동하는 예입니다.
기본 색상 범위는 빨강·노랑·초록·시안·파랑·마젠타의 여섯 개입니다. 각 범위가 중심각과 폭, 페더, 조정값을 별도로 가집니다. 전체 조정값에 선택한 범위의 조정량을 더해 최종 값을 구합니다.
이 선택은 색을 기준으로 합니다. 같은 파랑이 옷에도 있다면 함께 바뀔 수 있습니다. 배경만 바꾸려면 색상 범위 외에 마스크로 공간도 제한해야 합니다.
폭 안에서는 전부, 페더에서는 조금씩
중심 240°에서 폭이 30°라면 양쪽 15°씩, 225°~255°가 100% 적용 구간입니다. 그 바깥의 페더 구간에서는 적용량이 서서히 줄어 195°와 285°에서 0이 됩니다.
예를 들어 원래 색상각이 210°이면 중심에서 30° 떨어져 있습니다. 완전 적용 폭의 절반인 15°를 빼고 페더 30°로 나누면 적용량은 0.5입니다. 색조 −45° 중 −22.5°만 더해지는 식입니다.
Adobe 문서도 색상 범위와 완만한 경계 적용을 구분합니다. 포토샷은 원래 픽셀의 색상각과 중심 사이 거리로 가중치를 계산합니다. 여러 범위가 겹치면 각 기여량을 합칩니다.
360° 경계를 넘는 거리 계산
색상각은 0°와 360°가 이어집니다. 빨강 근처에서 359°와 1°를 358° 떨어진 색으로 취급하면 범위가 끊깁니다. 그래서 원을 따라 짧은 쪽의 거리를 구하도록 식을 만들었습니다.
const d = Math.abs(((h * 360 - band.center + 540) % 360) - 180),
w = clamp(1 - (d - band.width / 2) / band.feather);
hue += band.hue * w;
sat += band.saturation * w;
light += band.lightness * w;이 코드는 원래 색상각 h를 사용해 각 범위의 가중치 w를 구합니다. 색조를 바꾼 결과로 다음 범위를 다시 선택하는 구조가 아닙니다. 페더는 분모에 쓰이므로 0을 허용하지 않습니다.
표는 예제의 파랑 설정을 RGB에 적용한 결과입니다. 파란 표본은 변하고, 범위 밖의 갈색과 회색은 그대로 남는 것을 확인할 수 있습니다.
| 입력 RGB | 출력 RGB |
|---|---|
| 40 · 85 · 155 | 62 · 153 · 160 |
| 170 · 130 · 110 | 170 · 130 · 110 |
| 80 · 80 · 80 | 80 · 80 · 80 |
명도를 먼저 바꾸고 채도를 계산합니다
새 방식에서는 RGB 각 채널에 명도를 먼저 적용한 뒤 HSL로 바꿉니다. 명도가 음수이면 기존 채널값에 비율을 곱하고, 양수이면 흰색까지 남은 차이의 일부를 더합니다. 이후 색조 이동과 채도를 적용하고 RGB로 돌아갑니다.
const lit = (x: number) =>
light < 0
? x * (1 + light / 100)
: x + ((1 - x) * light) / 100;
[inputH, inputS, inputL] =
hsl(lit(r), lit(g), lit(b), scratch);채도는 양수와 음수의 식이 다릅니다. revision 2에서 +50은 채도를 2배로, −50은 절반으로 만듭니다. 0~1 범위를 넘는 결과는 제한합니다. 여기서 쓰는 채도는 명도를 적용한 뒤 얻은 inputS입니다.
| 설정 | 채도 계수 | 입력 S=0.2 |
|---|---|---|
| −50 | 1 − 0.5 | 0.1 |
| 0 | 1 | 0.2 |
| +50 | 1 ÷ (1 − 0.5) | 0.4 |
스포이드와 색상화는 따로 만들었습니다
색상 범위 스포이드는 클릭한 색의 색상각을 구하고, 가장 가까운 기본 범위를 찾아 중심각을 옮깁니다. RGB 차이가 너무 작은 회색은 색상각이 불안정하므로 선택 대상에서 제외합니다. 사진 속 물체의 윤곽을 찾는 기능은 아닙니다.
색상화(Colorize)를 켜면 여섯 범위의 조정을 건너뛰고, 지정한 색조와 채도를 사용합니다. 따라서 원래 채도가 0인 회색에도 색을 넣을 수 있습니다. 기존 색조를 이동하는 기능과는 목적이 다릅니다.
테스트에서는 빨강 범위 조정이 관계없는 파랑을 바꾸지 않는지, 빨강의 360° 경계가 이어지는지 확인했습니다. 회색의 색상화, 초기화 시 범위 조정 제거, 잘못된 페더값 거부도 함께 검사했습니다.
- 범위 스포이드클릭한 색의 색상각으로 범위의 중심을 설정합니다.
- 색상화원래 색조 대신 지정한 색조·채도로 통일합니다.
- 검증과 초기화무관한 색 유지, 색상 경계, 회색, 잘못된 범위값을 확인합니다.
구현 코드와 참고 자료
- 색상 범위 가중치·명도·채도·색상화 계산
Photoshot v0.16.0 · 실제 구현과 테스트 - 색상 범위 UI와 컨트롤
Photoshot v0.16.0 · 실제 구현과 테스트 - 색상 범위 스포이드
Photoshot v0.16.0 · 실제 구현과 테스트 - 범위 조정·색상화·초기화 테스트
Photoshot v0.16.0 · 실제 구현과 테스트 - Adobe · 색조·채도와 색상 범위 경계의 기능 설명
기능 의미를 비교하기 위한 참고 문서입니다. Adobe의 내부 구현 코드 출처는 아닙니다.
