색 좌표와 이미지 대표색 완전정복

컬러 도구는 HEX·RGB·HSL·CMYK 네 좌표계로 색을 상호 변환하는 컨버터와, 이미지에서 대표색 5개를 뽑아내는 분석기를 한 화면에 묶은 도구입니다. 두 기능은 서로 이어져 있습니다 — 이미지 분석이 찾아낸 대표색 스와치를 클릭하면 그 색이 곧바로 컨버터에 로드되어 네 좌표계 값과 알파를 함께 보여줍니다. 아래에서는 이 변환과 추출이 실제로 어떤 계산으로 동작하는지, 이 도구의 구현을 기준으로 정리합니다. 모든 처리는 브라우저 안에서 끝나므로 입력한 색이나 이미지가 서버로 전송되지 않습니다.

네 가지 색 좌표, 하나의 색

이 도구는 화면에 보이는 HEX·RGB·HSL·CMYK 네 필드를 각각 독립적으로 저장하지 않습니다. 내부에는 R·G·B·A(각 0–255) 정준(canonical) 값 하나만 있고, 네 필드는 그 정준값을 각 좌표계 문자열로 다시 포맷해 보여주는 창일 뿐입니다. 어느 필드를 편집하든 먼저 그 좌표계 파서가 입력을 RGBA로 해석하고, 해석에 성공하면 정준값을 갱신한 뒤 나머지 세 필드가 그 값으로부터 다시 계산되어 갱신됩니다 — HSL을 CMYK로 바로 바꾸는 직접 변환 코드는 없고, 항상 “X → RGBA → Y” 경로를 거칩니다. 그래서 같은 색이 네 가지로 다르게 적히는 이유는 단순합니다 — 코드 붙여넣기엔 HEX가, 채널별 수치 조정엔 RGB가, 색상·채도·명도를 나눠 만지고 싶을 땐 HSL이, 인쇄 근사치를 확인할 땐 CMYK가 각자 편한 상황이 다를 뿐 가리키는 색은 하나입니다.

정준값이 항상 RGBA 하나라는 점은 중요한 이점도 줍니다 — 필드를 오가며 표시만 바꿔볼 때는 오차가 누적되지 않습니다. 예를 들어 HSL 필드를 본 뒤 다시 RGB 필드를 봐도 그 사이에 값이 HSL로 “변환되어 저장”된 적이 없으므로 반올림 손실이 쌓이지 않습니다. 오차가 생기는 시점은 사용자가 실제로 어떤 필드를 편집해 정준값 자체를 바꿀 때뿐이며, 이는 값을 새로 입력하는 이상 피할 수 없는 반올림입니다.

HSL이 색 조정에 편한 이유

RGB는 빨강·초록·파랑 세 채널이 색상과 밝기를 한데 섞어 담고 있어서, 예를 들어 같은 파랑을 더 어둡게만 만들고 싶어도 R·G·B 세 값을 모두 눈대중으로 낮춰야 합니다. HSL은 색상(Hue, 0–360도)·채도(Saturation, 0–100%)·명도(Lightness, 0–100%) 세 축을 분리해, 색 자체(H)는 그대로 두고 명도(L)나 채도(S)만 움직이는 조정이 가능합니다. 버튼의 hover·pressed 상태처럼 “같은 색 계열에서 살짝 어둡게/밝게”를 만드는 톤앤매너 작업에서 HSL이 RGB보다 직관적인 이유입니다.

이 도구의 HSL 필드는 hsl(h, s%, l%) 또는 알파가 있으면 hsla(h, s%, l%, a) 형식으로 표시되고, 입력한 문자열은 표준 HSL→RGB 변환식으로 정준 RGBA에 반영됩니다. H는 0–360, S·L은 0–100 범위를 벗어나면 그 필드만 파싱에 실패해 빨간 테두리와 함께 오류가 표시되고, 나머지 필드는 마지막으로 유효했던 값을 그대로 유지합니다.

CMYK는 왜 화면 색과 다른가

화면(RGB)은 빛을 더해 밝은 색을 만드는 가산혼합이고, 인쇄(CMYK)는 잉크를 겹쳐 빛을 흡수시켜 어두운 색을 만드는 감산혼합입니다. 감산 혼합이라 잉크를 겹칠수록 어두워지는 CMYK는 화면이 빛을 더할수록 밝아지는 RGB 가산 혼합과 반대 방향으로 색을 섞습니다. 이 도구의 CMYK 변환은 K (검정) = 1 − max(R,G,B)/255를 먼저 구하고, C = (1 − R/255 − K) / (1 − K), M·Y도 같은 형태로 계산하는 나이브(naive) 공식입니다 — 대다수 웹 컨버터가 쓰는 방식과 같습니다. K가 1(완전 검정)이 되는 경우만 예외로 C=M=Y=0을 바로 반환해 0으로 나누기를 피합니다.

이 공식에는 ICC 프로파일이 전혀 없습니다. 즉 실제 인쇄기·잉크·용지의 특성을 전혀 반영하지 않는 device-dependent 근사치라, 같은 CMYK 수치라도 프린터나 인쇄소마다 실물 색이 달라질 수 있습니다. 화면에서 본 색과 인쇄물이 다르게 나오는 근본 원인이 바로 이 색 관리 정보의 부재입니다 — 정확한 인쇄색이 필요하다면 이 도구의 근사치 대신 실제 인쇄소가 제공하는 ICC 프로파일로 별도 변환해야 합니다.

게임 엔진과 알파

알파(투명도)를 값 손실 없이 그대로 왕복시키는 표기는 HEX 8자리(#RRGGBBAA) 하나뿐입니다 — 0–255 정수가 두 자리 16진수에 1:1로 담깁니다. RGBA·HSLA도 알파를 표현하지만, 표시할 때 0–1 소수 두 자리로 반올림하기 때문에 256단계가 101단계로 압축됩니다 — 알파 127은 0.5로 적히고 그 문자열을 다시 읽으면 128이 되며, 1은 0으로, 254는 1(완전 불투명처럼 보이는 표기)로 적힙니다. 0–254 범위의 알파 255개 중 155개가 이렇게 1만큼 어긋나지만, 어긋나는 폭은 항상 1 이하이고 정준값이 늘 RGBA 정수라 필드를 오가는 것만으로 오차가 쌓이지는 않습니다. 알파를 정확히 보존해야 한다면 HEX 8자리로 주고받으세요. 반면 CMYK는 인쇄 잉크 농도를 나타내는 모델이라 투명도 개념이 없습니다 — 이 도구에서 CMYK 필드를 편집하면 결과는 항상 완전 불투명(알파 255)으로 고정되고, 반대로 정준값에 알파가 있어도 CMYK로 포맷할 때는 그 값이 그냥 버려집니다. 이 도구의 알파는 0–255 정수(슬라이더와 숫자 입력 모두 이 범위)로 다뤄지는데, Unity의 Color 구조체나 Godot의 Color 타입처럼 채널을 0–1 부동소수점으로 표현하는 엔진 API에 그대로 옮기려면 값을 255로 나누는 변환이 한 단계 더 필요합니다.

네이티브 색상 피커(input type=color)는 브라우저 표준상 알파를 지원하지 않기 때문에, 이 도구는 피커와 별도로 알파 슬라이더·숫자 입력을 두어 투명도만 따로 조정할 수 있게 했습니다. 피커로 색을 고르면 R·G·B만 갱신되고 알파는 그대로 유지됩니다.

이미지에서 대표색을 뽑는 원리

대표색 추출은 다섯 단계로 이뤄지는 결정적(같은 입력엔 항상 같은 결과) 파이프라인입니다.

  1. 다운샘플 — 이미지의 긴 변이 256px보다 크면, 긴 변을 256px 이하로 맞추는 간격(스트라이드)만큼 건너뛰며 픽셀을 샘플링합니다. 원본 크기와 무관하게 검사하는 픽셀 수의 상한을 걸어 두는 처리입니다.
  2. 알파 필터 — 샘플링된 픽셀 중 알파가 128 미만인 픽셀(완전 투명이든 반투명이든)은 이후 집계에서 통째로 제외됩니다.
  3. 양자화 — 남은 픽셀을 R·G·B 채널당 5비트(32단계)로 뭉뚱그려 버킷 키를 만들고, 버킷마다 등장 횟수와 실제 R·G·B 합을 누적합니다(나중에 평균 내면 그 버킷의 센트로이드 색이 됩니다).
  4. 희석 버킷 제거 — 전체 집계 픽셀 수의 0.5% 미만인 버킷은 제거합니다. 다만 이렇게 걸러낸 뒤 남는 버킷이 하나도 없으면(사진처럼 뚜렷한 지배색이 없는 이미지) 이 제거 단계를 건너뛰고 원래 버킷을 그대로 씁니다.
  5. 근접 병합 — 남은 버킷을 등장 횟수 내림차순으로 훑으면서, R·G·B에 0.3·0.59·0.11 가중치(사람 눈이 초록에 더 민감한 정도를 반영한 밝기 가중치)를 적용한 제곱 거리가 400 미만인 기존 병합군을 찾으면 그 병합군에 합치고(카운트와 색을 가중 평균), 없으면 새 병합군을 만듭니다. 가장 가까운 병합군이 아니라 조건을 만족하는 첫 병합군에 합쳐지는 간단한 그리디 방식입니다.
  6. 랭킹 — 병합이 끝난 버킷을 다시 등장 횟수 내림차순으로 정렬해 상위 5개만 남기고, 각 버킷의 색은 병합된 센트로이드 평균, 사용률은 그 버킷 카운트를 집계 총 픽셀 수로 나눈 백분율로 계산합니다.

이미지가 전부 투명하거나 유효 픽셀이 하나도 없으면 빈 배열을 반환하고, 이 도구는 “추출할 대표색이 없습니다(전부 투명/빈 이미지)” 배너를 보여줍니다. 색이 다섯 개보다 적게 나오는 이미지는 있는 만큼만 보여주고 빈 자리를 채우지 않으며, 단색 이미지는 대표색 1개가 100%로 나옵니다.

사용 순서

  1. 이미지 업로드 없이도 바로 쓸 수 있습니다 — HEX·RGB·HSL·CMYK 필드 중 아무 곳이나 직접 입력하거나, 네이티브 색상 피커로 고르거나, EyeDropper API를 지원하는 브라우저(Chromium 계열)라면 스포이드 버튼으로 화면의 아무 색이나 추출합니다.
  2. 알파(투명도)가 필요하면 색상 피커 옆의 알파 슬라이더나 숫자 입력(0–255)으로 따로 조정합니다.
  3. 원하는 좌표계 필드 옆의 [복사] 버튼을 누르면 그 표기 문자열이 클립보드에 복사되고, 버튼 라벨이 잠깐 “복사됨”으로 바뀌어 확인할 수 있습니다.
  4. 이미지의 톤앤매너를 뽑고 싶다면 “이미지 대표색 추출” 카드에 이미지를 끌어다 놓거나 클릭해 불러옵니다. 상위 대표색 5개가 HEX 값과 사용률(%)이 적힌 스와치로 나타납니다.
  5. 마음에 드는 스와치를 클릭하면 그 색이 곧바로 위쪽 컨버터로 로드되어 HEX·RGB·HSL·CMYK 값과 함께 표시됩니다.

주의

  • 잘못된 형식을 입력하면 그 필드에만 빨간 테두리와 오류 메시지가 뜨고, 나머지 필드와 정준값은 마지막으로 유효했던 값을 그대로 유지합니다 — 잘못된 입력으로 전체 값이 초기화되거나 도구가 멈추지 않습니다.
  • CMYK 필드는 알파를 표현하지 않습니다. CMYK로 값을 입력하면 결과는 항상 완전 불투명(알파 255)이 되고, 정준값에 이미 알파가 있어도 CMYK로 포맷할 때는 그 값이 버려집니다.
  • CMYK 수치는 ICC 프로파일 없는 근사치입니다. 인쇄물과 정확히 맞아야 하는 작업이라면 실제 인쇄소의 색 관리 프로파일로 별도 변환하세요.
  • 스포이드 버튼은 EyeDropper API를 지원하는 브라우저에서만 나타납니다 — 지원하지 않는 브라우저에서는 버튼 자체가 보이지 않습니다(기능 감지로 숨김).
  • 대표색 추출은 알파가 128 미만인 픽셀을 통째로 제외합니다. 반투명 그러데이션이 많은 이미지는 눈에 보이는 인상과 대표색 목록의 사용률이 다르게 느껴질 수 있습니다.
  • 안티에일리어싱 경계의 전이색처럼 이미지 전체의 0.5%에 못 미치는 색은 자동으로 걸러집니다 — 원본에 분명히 있던 색이 대표색에 없다면 대개 이 규칙 때문입니다.

자주 묻는 질문

Q. HEX, RGB, HSL, CMYK는 뭐가 다른가요?
네 표기 모두 같은 색을 가리키는 서로 다른 좌표계일 뿐입니다. 이 도구는 내부적으로 모든 색을 R·G·B·A(0–255) 정준값 하나로 들고 있다가, 화면에는 그 값을 각 좌표계 문자열로 다시 포맷해 보여줍니다. HEX(#RRGGBB)는 코드에 붙여넣기 좋고, RGB는 채널별 수치를 직접 다룰 때, HSL은 색상·채도·명도를 따로 조정할 때, CMYK는 인쇄 감산혼합 근사치가 필요할 때 편합니다.

Q. CMYK로 바꾼 색이 화면과 달라 보여요.
이 도구의 CMYK 변환은 K = 1 − max(R,G,B)/255 공식을 쓰는 나이브(naive) 변환으로, ICC 프로파일 같은 색 관리 정보를 전혀 참조하지 않습니다. 실제 인쇄기·잉크·용지마다 색이 달라지는 device-dependent 특성을 이 계산은 반영하지 못하므로, 화면에서 본 색과 실제 인쇄물이 다르게 나올 수 있습니다. 정확한 인쇄색이 필요하다면 인쇄소가 제공하는 ICC 프로파일로 별도 변환해야 합니다.

Q. 알파(투명도)는 어떤 표기에서 되나요?
값 손실 없이 알파를 그대로 왕복시키는 표기는 HEX 8자리(#RRGGBBAA)뿐입니다. RGBA·HSLA도 알파를 표현하지만 표시할 때 0–1 소수 두 자리로 반올림하므로 256단계가 101단계로 압축됩니다 — 알파 127은 0.5로 적혀 다시 읽으면 128이 되는 식으로, 0–254 범위의 255개 값 중 155개가 1만큼 어긋납니다(어긋나는 폭은 항상 1 이하이고, 정준값이 RGBA 정수라 오차가 누적되지는 않습니다). 반면 CMYK 필드는 알파를 표현하지 않습니다 — 인쇄 잉크 농도를 나타내는 모델이라 투명도 개념 자체가 없고, 이 도구에서 CMYK 값을 입력하면 항상 완전 불투명(알파 255)으로 처리됩니다.

Q. 이미지 대표색은 어떻게 골라지나요?
다섯 단계를 거칩니다. ① 긴 변이 256px를 넘으면 그 이하로 샘플 간격을 벌려 다운샘플하고, ② 알파가 128 미만인 픽셀(투명·반투명)은 카운트에서 제외하고, ③ 채널당 5비트(32단계)로 색을 양자화해 버킷을 만들고, ④ 전체 카운트의 0.5% 미만인 저인구 버킷을 제거하고, ⑤ 남은 버킷 중 가중 RGB 거리가 가까운 것끼리 병합한 뒤 사용률(카운트) 상위 5개만 남깁니다.

Q. 왜 원본에 있는 색이 대표색에 안 나오나요?
두 가지 이유가 있습니다. 안티에일리어싱 경계처럼 아주 조금씩만 존재하는 전이색은 양자화 버킷 하나하나가 전체의 0.5%를 넘지 못해 자동으로 제거됩니다. 또한 알파가 128 미만인 반투명 픽셀은 애초에 집계 대상에서 빠집니다. 둘 다 "적지만 존재하는 색"보다 "화면을 대표하는 색"을 우선하기 위한 의도된 설계입니다 — 다만 이미지 전체에 뚜렷한 지배색이 없어 모든 버킷이 0.5% 미만이 되면(사진 등) 이 제거 단계를 건너뛰고 있는 버킷을 그대로 씁니다.

관련 가이드

컬러 도구 열기

최종 업데이트 2026-08-21