이번에 작업한 부분
포토샷 포토필터의 색·농도·명도 유지 설정과 레이어 합성을 연결했습니다.
포토샷 포토필터의 색·농도·명도 유지 설정과 레이어 합성을 연결했습니다.
개발 기록 재구성 · 공개 코드 v0.16.0 기준 / 2026.10.13
구현 과정 읽기 ↓
Development journal / 10
기존 개발 기록과 공개 코드를 바탕으로 구현 과정을 정리했습니다. 아래 인물 사진은 2026.10.13에 새로 제작한 동작 예시입니다.
포토샷 포토필터의 색·농도·명도 유지 설정과 레이어 합성을 연결했습니다.
필터색과 농도로 색 변환을 계산하고, 그 결과를 마스크·불투명도와 함께 합성합니다.
필터 농도와 레이어 불투명도는 서로 다른 단계에 작용합니다. 두 숫자를 곱해 하나로 줄이면 같은 결과라고 볼 수 없습니다.
필터 이름과 색상값은 설정으로, 실제 색 계산은 엔진으로 분리했습니다. 이전 프로젝트에는 예전 혼합식을 유지하고 새 계산은 revision으로 구분했습니다.
문서는 옵션의 의미를 확인하는 데 참고했습니다. 외부 GitHub에서 계산 코드를 가져온 기록은 확인되지 않았습니다.
이번 사진은 Cooling (80), 농도 22%, 밝기 유지로 편집했습니다. 화면의 설정과 내보낸 결과를 함께 남겼습니다.

AFTERBEFORE이번에는 포토샷의 쿨링 필터를 새 인물 사진에 적용했습니다. 새 실습 화면과 기존 필터 계산 설명을 나눠 정리했습니다.
사진 위를 좌우로 움직여 비교하세요. 키보드로는 비교 막대에 초점을 맞춘 뒤 방향키를 사용하면 됩니다.
인물 사진은 새로 생성한 AI 이미지입니다. 편집 결과는 실제 Photoshot에서 적용하고 내보냈습니다. 아래 값은 이 사진의 실습값이며 모든 사진에 맞는 권장값은 아닙니다.
STEP 01 / 도구 찾기
사진을 연 뒤 상단 Add Adjustment에서 Photo Filter를 선택합니다. 아래는 실제 편집기에서 해당 도구의 위치를 확인한 화면입니다.

STEP 02 / 직접 조절
Cooling (80), 필터 색 #006dff, Density 22를 적용합니다. Preserve Luminosity를 켜고 따뜻한 원본과 비교합니다.

STEP 03 / 레이어 표시를 껐다 켜거나 Hold to Compare로 원본을 비교한 뒤 File → Export As… → Download로 결과를 저장합니다. 위 전후 비교의 AFTER는 이 편집기에서 직접 내보낸 이미지입니다. 화면을 누르면 원본 크기로 확대됩니다.
02 / Behind the tool
아래는 기존 작업기의 공개 코드 v0.16.0 기준 설명과 계산 예제입니다. 2026.10.01 기록의 수치·검증 설명을 보존했습니다. 위의 2026.10.13 새 사진 실습과 설정값은 다를 수 있으며, 현재 편집기의 모든 기능을 이 버전의 코드와 동일하다고 설명하는 것은 아닙니다.
릴스에서는 Warming (85)에 해당하는 색 #ec8a00을 사용했습니다. 농도를 35에서 55로 올린 뒤, 레이어 불투명도를 85%로 낮춰 마무리했습니다. 명도 유지는 켜 두었습니다.
필터 목록은 이름과 HEX 색상값을 연결한 배열입니다. 목록에서 고르면 색상값이 레이어에 저장되고, 사용자가 직접 색을 골라도 같은 계산을 거칩니다. 화면에 ‘사용자 정의 색상’이라고 보여도 저장된 필터색은 유지됩니다.
농도는 0~100, 기본값은 25입니다. 이름이 붙은 필터와 직접 고른 색을 구분해 서로 다른 알고리즘을 적용하는 구조는 아닙니다.
새 포토필터는 먼저 sRGB 채널값을 선형 값으로 바꿉니다. 어두운 값은 나누기로, 나머지는 거듭제곱으로 처리하는 구간별 변환입니다. 필터색에도 같은 변환을 적용합니다.
const linear = s => s <= 0.04045
? s / 12.92
: ((s + 0.055) / 1.055) ** 2.4;필터색을 XYZ 변환 행렬에 넣어 세 축의 반응을 구하고, 농도에 따라 변화량을 정합니다. 이 값을 다시 RGB로 돌아오는 행렬과 곱해 3 × 3 변환 행렬을 만듭니다. 픽셀마다 이 행렬을 적용한 뒤 sRGB로 돌아옵니다.
색 공간 변환에는 코드에 정의한 고정 행렬을 사용합니다. 모든 ICC 프로파일을 읽어 처리하는 색 관리 시스템이나 실제 렌즈 필터의 분광 특성을 재현한 모델은 아닙니다.
행렬을 적용한 결과에 명도 유지 옵션이 켜져 있으면 color 혼합 함수를 호출합니다. 원본의 밝기 기준에 맞춰 필터 결과를 조정하는 단계입니다.
if (v.preserve) {
scratch[0] = r;
scratch[1] = g;
scratch[2] = b;
blendRGB(scratch, out, 'color', out);
}이 혼합 함수에서 밝기는 0.3R + 0.59G + 0.11B로 구합니다. 필터 결과가 원본과 같은 기준 밝기를 갖도록 채널을 이동하고, 허용 범위를 넘는 색은 다시 조정합니다. 단순히 세 채널을 개별적으로 잘라내는 것과는 다릅니다.
검정 픽셀은 행렬을 통과해도 검정입니다. 일정한 주황색을 RGB에 더하는 방식과 비교할 때 이 차이를 바로 확인할 수 있습니다.
농도와 레이어 불투명도는 적용되는 위치가 다릅니다. 농도는 색 변환 행렬을 만들 때 들어가고, 불투명도는 필터 결과와 원본을 마지막에 섞을 때 사용합니다.
amount = opacity * maskAlpha;
result = before + (filtered - before) * amount;위 코드는 표준 혼합의 마지막 단계를 간단히 정리한 것입니다. 마스크가 없으면 maskAlpha는 1입니다. 원본에 변화량의 85%를 더하는 계산과, 농도를 55 × 0.85 = 46.75로 바꿔 처음부터 처리하는 계산은 일반적으로 다릅니다.
색 공간 변환과 범위 제한, 명도 유지가 중간에 들어가기 때문입니다. 표는 같은 입력을 두 방식으로 처리한 결과입니다. 아주 가까운 값이 나올 수 있지만 서로 같은 설정은 아닙니다.
| 입력 RGB | 55 / 85% | 46.75 / 100% |
|---|---|---|
| 128 · 128 · 128 | 143 · 123 · 113 | 142 · 123 · 114 |
| 170 · 130 · 110 | 180 · 127 · 101 | 179 · 127 · 102 |
| 40 · 85 · 155 | 69 · 76 · 124 | 69 · 76 · 125 |
필터 목록은 adjustment-presets.ts, 색 변환은 adjustments.ts, 명도 유지에 쓰는 혼합은 blend.ts에 나눠 두었습니다. 새 필터 이름과 색을 추가할 때 픽셀 계산을 새로 작성할 필요가 없습니다.
예전 파일에서는 RGB를 필터색과 직접 섞는 계산을 사용합니다. 새 방식과 구분하는 기준은 revision입니다. 같은 농도라도 계산 경로가 달라지므로, 저장한 파일의 결과를 유지하려면 이 구분이 필요합니다.
Adobe 문서는 필터색·농도·명도 유지의 기능을 설명하는 참고 자료로 사용했습니다. 위의 행렬과 혼합 코드는 포토샷 저장소의 실제 구현입니다. 설명용 표본도 그 코드를 실행해 만들었습니다.
| 파일 | 담당하는 부분 |
|---|---|
| adjustment-presets.ts | 필터 이름과 HEX 색상 |
| adjustments.ts | 행렬 구성과 픽셀 변환 |
| blend.ts | 색상 혼합과 밝기 기준 |
| adjustPixels | 레이어 불투명도·마스크 합성 |