이번에 작업한 부분
포토샷의 활기·채도와 피부색 보호 옵션이 어떤 계산을 고르는지 정리했습니다.
포토샷의 활기·채도와 피부색 보호 옵션이 어떤 계산을 고르는지 정리했습니다.
개발 기록 재구성 · 공개 코드 v0.16.0 기준 / 2026.10.13
구현 과정 읽기 ↓
Development journal / 06
기존 개발 기록과 공개 코드를 바탕으로 구현 과정을 정리했습니다. 아래 인물 사진은 2026.10.13에 새로 제작한 동작 예시입니다.
포토샷의 활기·채도와 피부색 보호 옵션이 어떤 계산을 고르는지 정리했습니다.
보호 옵션이 켜진 새 조정은 측정한 RGB 응답표를 보간하고, 꺼진 경우에는 HSL 채도에 따른 자체 계산을 사용합니다.
모든 색의 채도를 같은 비율로 올리는 것만으로는 활기의 차등 반응을 표현하기 어렵습니다. 피부색 보호라는 이름이 얼굴 인식처럼 받아들여지는 점도 설명해야 했습니다.
초기에는 glfx.js의 활기 처리 사례를 검토했습니다. 이후 측정 RGB 응답표를 사용하는 경로를 추가했습니다. 현재 보호 옵션은 얼굴을 찾지 않으며 같은 RGB에는 같은 계산을 적용합니다.
glfx.js는 초기 참고 사례입니다. 현재 측정 응답표의 출처가 아니며 포토샷은 별도 계산과 자체 측정 데이터를 사용합니다.
이번 사진에 활기 +30, 채도 −5를 적용했습니다. 공개 코드에는 기본값·극단값·알파 보존을 확인하는 검사가 포함돼 있습니다.

AFTERBEFORE포토샷에서 활기와 채도를 함께 조절해 봤습니다. 피부색 보호는 얼굴 인식 AI가 아니라 색에 따른 처리라는 점, 그래서 사진마다 결과를 확인해야 한다는 점도 작업기에 정리했습니다.
사진 위를 좌우로 움직여 비교하세요. 키보드로는 비교 막대에 초점을 맞춘 뒤 방향키를 사용하면 됩니다.
인물 사진은 새로 생성한 AI 이미지입니다. 편집 결과는 실제 Photoshot에서 적용하고 내보냈습니다. 아래 값은 이 사진의 실습값이며 모든 사진에 맞는 권장값은 아닙니다.
STEP 01 / 도구 찾기
사진을 연 뒤 상단 Add Adjustment에서 Vibrance를 선택합니다. 아래는 실제 편집기에서 해당 도구의 위치를 확인한 화면입니다.

STEP 02 / 직접 조절
Vibrance 30, Saturation −5를 입력하고 Protect Skin Tones를 켭니다. 꽃과 의상 색을 피부와 함께 비교합니다.

STEP 03 / 레이어 표시를 껐다 켜거나 Hold to Compare로 원본을 비교한 뒤 File → Export As… → Download로 결과를 저장합니다. 위 전후 비교의 AFTER는 이 편집기에서 직접 내보낸 이미지입니다. 화면을 누르면 원본 크기로 확대됩니다.
02 / Behind the tool
아래는 기존 작업기의 공개 코드 v0.16.0 기준 설명과 계산 예제입니다. 2026.10.01 기록의 수치·검증 설명을 보존했습니다. 위의 2026.10.13 새 사진 실습과 설정값은 다를 수 있으며, 현재 편집기의 모든 기능을 이 버전의 코드와 동일하다고 설명하는 것은 아닙니다.
실제 예제는 활기 +60, 채도 +10, 피부색 보호 켬입니다. 먼저 활기 응답을 적용하고, 그 결과에 채도 응답을 적용합니다. 같은 원본에 두 결과를 각각 구해 더하는 방식은 아닙니다.
Adobe의 활기 설명은 채도가 낮은 색을 더 조절하고 피부색의 과도한 채도를 억제하는 동작을 다룹니다. 포토샷에서는 이 반응을 비교하기 위해 측정 응답표를 사용하는 경로와 HSL 계산 경로를 나눴습니다.
현재 기본값은 피부색 보호 켬입니다. 이 선택이 실제로 어떤 계산을 고르는지는 아래에서 구분해 설명합니다.
R·G·B를 각각 17단계로 나누면 17 × 17 × 17 = 4,913개의 색 조합이 나옵니다. 각 색의 입력값과 조정 후 출력값을 대응시킨 자료가 이 구현의 RGB 응답표입니다.
슬라이더도 −100부터 +100까지 10 간격으로 나눕니다. 활기와 채도에 각각 21개씩, 총 42개의 응답 자료가 들어갑니다. 예를 들어 +65는 +60과 +70 표 사이를 절반씩 보간합니다.
자료 파일의 주석은 이 표를 Photoshop 27.3.1에서 측정한 합성 색상 격자의 응답으로 기록하고 있습니다. Adobe가 배포한 프리셋이나 Photoshop 내부 소스 코드를 가져온 것은 아닙니다. 샘플 사이의 결과는 근사이며, 모든 색·작업 공간에서 동일하다고 보장하지 않습니다.
아래 코드는 세 축을 따라 돌며 계산하는 내부 반복문의 일부입니다. rf, gf, bf는 각 축에서 입력 색이 놓인 비율입니다. 한 꼭짓점의 가중치는 세 비율의 곱으로 구합니다.
w = (x ? rf : 1 - rf)
* (y ? gf : 1 - gf)
* (z ? bf : 1 - bf);
dr += (table[i] - grid[rr]) * w;
dg += (table[i + 1] - grid[gg]) * w;
db += (table[i + 2] - grid[bb]) * w;표의 출력 자체가 아니라 입력에서 얼마나 변했는지를 섞는 방식입니다. 마지막에는 원래 RGB에 이 변화량을 더합니다. 슬라이더가 0이면 이 과정을 건너뛰고 입력값을 그대로 돌려줍니다.
색상표는 사진에서 추측한 색이 아니라, 정해 둔 RGB 네 개를 실제 함수에 넣은 결과입니다. 숫자는 8비트로 반올림했습니다.
이 옵션에는 얼굴 인식이나 인물 영역을 찾는 AI가 없습니다. revision === 2 && v.skin 조건이면 앞서 설명한 측정 응답표를 사용합니다. 따라서 같은 RGB라면 피부든 벽이든 같은 결과가 나옵니다.
옵션을 끄면 HSL의 채도를 이용한 계산으로 전환합니다. 활기의 가중치에 1 − s를 넣어 기존 채도가 낮을수록 상대적인 증가율을 키웁니다. 원래 채도 s에 곱하므로 완전한 회색에 임의의 색을 만들지는 않습니다.
const gain = (v.vibrance / 100) * (1 - s);
const nextS = clamp(
s * (1 + gain) * (1 + v.saturation / 100)
);위 코드는 보호 끔 경로의 식을 읽기 쉽게 정리한 것입니다. 켬과 끔은 동일한 계산의 강도 차이가 아니라, 사용하는 계산 경로 자체가 다릅니다.
| 설정 | 계산 경로 |
|---|---|
| 보호 켬 | 측정 RGB 응답표 → 활기 → 채도 |
| 보호 끔 | HSL 채도 기반의 근사 계산 |
| 공간 선택 | 얼굴·피사체 선택 기능 없음 |
색을 바꾸는 조정이 투명도까지 바꾸면 합성 결과도 달라집니다. 활기 테스트에는 반투명 픽셀을 넣고, 조정 전후의 알파값이 그대로인지 확인하는 항목을 두었습니다.
피부색 보호를 켰을 때와 껐을 때 모두 기본값은 원본과 일치해야 합니다. −100과 +100 같은 극단값도 검사하고, 허용 범위를 벗어난 값이나 지원하지 않는 revision은 거부합니다.
테스트는 색이 실제로 변하는지와 데이터가 유지되는지를 확인합니다. 측정 격자 밖의 정확도를 보장하는 Photoshop 대조 시험과는 구분해야 합니다. 샘플 수와 보간 방식은 결과를 더 정밀하게 다듬을 때 검토할 부분입니다.