이번에 작업한 부분
포토샷 선택 색상에서 아홉 색 계열의 C·M·Y·K 조정과 공통 합성 구조를 정리했습니다.
포토샷 선택 색상에서 아홉 색 계열의 C·M·Y·K 조정과 공통 합성 구조를 정리했습니다.
개발 기록 재구성 · 공개 코드 v0.16.0 기준 / 2026.10.13
구현 과정 읽기 ↓
Development journal / 17
기존 개발 기록과 공개 코드를 바탕으로 구현 과정을 정리했습니다. 아래 인물 사진은 2026.10.13에 새로 제작한 동작 예시입니다.
포토샷 선택 색상에서 아홉 색 계열의 C·M·Y·K 조정과 공통 합성 구조를 정리했습니다.
계열마다 네 값, 총 36개 설정을 저장합니다. 기능별 RGB 계산 뒤에는 마스크·불투명도·합성 모드 처리를 공통으로 적용합니다.
같은 슬라이더 수치라도 상대값과 절대값의 결과가 다릅니다. 기능마다 마스크와 합성을 다시 만들면 처리 기준이 달라질 위험도 있습니다.
Adobe 문서로 상대·절대 옵션의 의미를 확인하고 RGB 기반 자체 근사식을 작성했습니다. 기능별 색 계산과 공통 레이어 합성을 분리했습니다.
Adobe 문서의 기능 의미를 참고했습니다. 비공개 알고리즘이나 외부 GitHub 코드를 가져온 구현으로 설명하지 않습니다.
이번 사진은 파랑의 Cyan +20·Magenta −15를 상대값으로 적용했습니다. 아홉 색 계열을 고르는 기능이며 인물·배경을 자동으로 나누는 선택은 아닙니다.

AFTERBEFORE포토샷에서 파랑 계열을 상대 방식으로 조절했습니다. 색조·채도와 무엇이 다른지, 상대·절대 방식은 왜 따로 있는지 공개 코드와 함께 정리했습니다.
사진 위를 좌우로 움직여 비교하세요. 키보드로는 비교 막대에 초점을 맞춘 뒤 방향키를 사용하면 됩니다.
인물 사진은 새로 생성한 AI 이미지입니다. 편집 결과는 실제 Photoshot에서 적용하고 내보냈습니다. 아래 값은 이 사진의 실습값이며 모든 사진에 맞는 권장값은 아닙니다.
STEP 01 / 도구 찾기
사진을 연 뒤 상단 Add Adjustment에서 Selective Color를 선택합니다. 아래는 실제 편집기에서 해당 도구의 위치를 확인한 화면입니다.

STEP 02 / 직접 조절
Color Range에서 Blue, 방식은 Relative를 선택합니다. Cyan 20, Magenta −15, Yellow 0, Black 0으로 파란 의상을 조절합니다.

STEP 03 / 레이어 표시를 껐다 켜거나 Hold to Compare로 원본을 비교한 뒤 File → Export As… → Download로 결과를 저장합니다. 위 전후 비교의 AFTER는 이 편집기에서 직접 내보낸 이미지입니다. 화면을 누르면 원본 크기로 확대됩니다.
02 / Behind the tool
아래는 기존 작업기의 공개 코드 v0.16.0 기준 설명과 계산 예제입니다. 2026.10.01 기록의 수치·검증 설명을 보존했습니다. 위의 2026.10.13 새 사진 실습과 설정값은 다를 수 있으며, 현재 편집기의 모든 기능을 이 버전의 코드와 동일하다고 설명하는 것은 아닙니다.
빨강·노랑·초록·청록·파랑·자홍·흰색·중간색·검정을 고를 수 있습니다. 각 계열에 C·M·Y·K 네 값이 있으므로 조정값은 36개이며, 범위는 각각 −100~100입니다.
상단 사진은 파랑의 C +20·M −25·Y −20, 빨강의 C −20·M +10·Y +15, 검정의 K +10을 적용한 결과입니다. 나머지는 0, 상대값 켬, 불투명도 100%입니다.
색상 계열은 피사체 선택과 다릅니다. 같은 계열의 옷과 배경은 함께 영향을 받을 수 있습니다. 특정 부분에만 적용하려면 마스크를 사용합니다.
원래 픽셀의 가장 큰 채널값을 hi, 가장 작은 값을 lo, 나머지를 mid로 둡니다. 파랑이 가장 큰 채널이라면 hi−mid만큼 파랑 계열의 조정에 반영합니다.
weights[4] = b === hi ? hi - mid : 0;
weights[6] = clamp((lo - 0.5) * 2);
weights[7] = 1 - Math.abs(hi + lo - 1);
weights[8] = clamp((0.5 - hi) * 2);뒤의 세 식은 흰색·중간색·검정의 가중치입니다. 중간색은 이름과 달리 무채색만 고르는 스위치가 아닙니다. 현재 식에 맞는 유채색도 영향을 받을 수 있습니다.
계열별 기여량을 더하므로 여러 계열의 조정이 한 픽셀에 겹칠 수 있습니다. 가중치의 합을 다시 1로 정규화하지는 않습니다.
| 계열 | 가중치의 기준 |
|---|---|
| 빨강·초록·파랑 | 해당 채널이 최댓값일 때 hi−mid |
| 노랑·청록·자홍 | 대응하는 채널이 최솟값일 때 mid−lo |
| 흰색 | 세 채널 중 가장 어두운 값도 밝은 정도 |
| 검정 | 세 채널 중 가장 밝은 값도 어두운 정도 |
C·M·Y는 각각 R·G·B에 대응하는 조절값으로 사용합니다. 원래 RGB를 인쇄용 CMYK 프로파일로 변환한 뒤 편집하는 구조는 아닙니다.
delta += weight * (
ink * (relative ? 1 - input[c] : 1)
+ black * (relative ? input[c] : 1)
);
out[c] = clamp(input[c] - delta);상대값에서는 잉크 성분에 1−입력값, 검정 성분에는 입력값을 곱합니다. 절대값에서는 이 두 계수가 1입니다. 두 방식 모두 해당 색상 계열의 가중치는 적용합니다.
같은 슬라이더값이라도 원래 채널값에 따라 상대값과 절대값의 차이가 달라집니다. 세부 계산은 이 프로젝트의 구현이며 Adobe의 비공개 알고리즘을 인용한 식이 아닙니다.
검정 계열의 K +10만 생각해 보면 동작이 더 분명합니다. 회색 64의 검정 가중치는 약 0.498입니다. 상대값에서는 여기에 원래 채널값과 0.1을 곱한 양을 뺍니다.
같은 설정을 절대값으로 바꾸면 원래 채널값을 곱하는 단계가 빠집니다. 그래서 어두운 회색에서는 변화량이 더 큽니다. 아래 표는 다른 계열의 조정값을 모두 0으로 둔 별도 실험입니다.
모든 계열의 변화량을 더한 뒤 0~1 범위를 제한합니다. 강한 설정에서는 서로 다른 값이 같은 검정이나 흰색에 걸릴 수 있으므로, 숫자를 크게 올리는 것이 항상 더 많은 디테일을 보여 주는 것은 아닙니다.
| 원래 회색 | K+10 상대값 | K+10 절대값 |
|---|---|---|
| 32 | 30 | 13 |
| 64 | 61 | 51 |
| 96 | 94 | 90 |
| 160 | 160 | 160 |
각 기능은 입력 RGB를 새로운 RGB로 바꾸는 계산을 맡습니다. 불투명도, 마스크, 합성 모드, 알파 보존은 공통 경로에서 처리합니다. 이 구분 덕분에 새 조정을 추가할 때 같은 합성 코드를 반복해서 만들지 않았습니다.
레이어별 설정을 저장하고, 예전 계산이 필요한 프로젝트는 revision으로 구분합니다. 이번에 실행한 기존 테스트에서는 16종 설정의 저장·불러오기, 이전 버전 결과 유지, 디더링의 일관성도 확인했습니다.
개발기 01~16편은 이렇게 기능별 계산과 공통 구조를 나눠 기록한 글입니다. Adobe 문서는 기능 의미를 확인하는 참고 자료로, GitHub 코드는 실제 구현의 근거로 연결했습니다.